1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_TAG "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 {
1689 #ifdef TARGET_TS_MAKEUP
1690 memset(&mFaceRect, -1, sizeof(mFaceRect));
1691 #endif
1692 getLogLevel();
1693 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_QCAMERA2HWI);
1694 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1695 mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1696 mCameraDevice.common.close = close_camera_device;
1697 mCameraDevice.ops = &mCameraOps;
1698 mCameraDevice.priv = this;
1699
1700 mDualCamera = is_dual_camera_by_idx(cameraId);
1701
1702 pthread_mutex_init(&m_lock, NULL);
1703 pthread_cond_init(&m_cond, NULL);
1704
1705 m_apiResultList = NULL;
1706
1707 pthread_mutex_init(&m_evtLock, NULL);
1708 pthread_cond_init(&m_evtCond, NULL);
1709 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1710
1711
1712 pthread_mutex_init(&m_int_lock, NULL);
1713 pthread_cond_init(&m_int_cond, NULL);
1714
1715 memset(m_channels, 0, sizeof(m_channels));
1716
1717 memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
1718
1719 memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
1720
1721 memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
1722 memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
1723 memset(&mJpegHandle, 0, sizeof(mJpegHandle));
1724 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
1725
1726 mDeferredWorkThread.launch(deferredWorkRoutine, this);
1727 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1728
1729 pthread_mutex_init(&mGrallocLock, NULL);
1730 mEnqueuedBuffers = 0;
1731 mFrameSkipStart = 0;
1732 mFrameSkipEnd = 0;
1733 mLastPreviewFrameID = 0;
1734
1735 //Load and read GPU library.
1736 lib_surface_utils = NULL;
1737 LINK_get_surface_pixel_alignment = NULL;
1738 mSurfaceStridePadding = CAM_PAD_TO_32;
1739 lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
1740 if (lib_surface_utils) {
1741 *(void **)&LINK_get_surface_pixel_alignment =
1742 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
1743 if (LINK_get_surface_pixel_alignment) {
1744 mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
1745 }
1746 dlclose(lib_surface_utils);
1747 }
1748 }
1749
1750 /*===========================================================================
1751 * FUNCTION : ~QCamera2HardwareInterface
1752 *
1753 * DESCRIPTION: destructor of QCamera2HardwareInterface
1754 *
1755 * PARAMETERS : none
1756 *
1757 * RETURN : none
1758 *==========================================================================*/
~QCamera2HardwareInterface()1759 QCamera2HardwareInterface::~QCamera2HardwareInterface()
1760 {
1761 LOGH("E");
1762
1763 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1764 mDeferredWorkThread.exit();
1765
1766 if (mMetadataMem != NULL) {
1767 delete mMetadataMem;
1768 mMetadataMem = NULL;
1769 }
1770
1771 if (m_pFovControl) {
1772 delete m_pFovControl;
1773 m_pFovControl = NULL;
1774 }
1775
1776 m_perfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA);
1777 lockAPI();
1778 m_smThreadActive = false;
1779 unlockAPI();
1780 m_stateMachine.releaseThread();
1781 closeCamera();
1782 m_perfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA);
1783
1784 pthread_mutex_destroy(&m_lock);
1785 pthread_cond_destroy(&m_cond);
1786 pthread_mutex_destroy(&m_evtLock);
1787 pthread_cond_destroy(&m_evtCond);
1788 pthread_mutex_destroy(&m_int_lock);
1789 pthread_cond_destroy(&m_int_cond);
1790 pthread_mutex_destroy(&mGrallocLock);
1791 LOGH("X");
1792 }
1793
1794 /*===========================================================================
1795 * FUNCTION : deferPPInit
1796 *
1797 * DESCRIPTION: Queue postproc init task to deferred thread
1798 *
1799 * PARAMETERS : none
1800 *
1801 * RETURN : uint32_t job id of pproc init job
1802 * 0 -- failure
1803 *==========================================================================*/
deferPPInit()1804 uint32_t QCamera2HardwareInterface::deferPPInit()
1805 {
1806 // init pproc
1807 DeferWorkArgs args;
1808 DeferPProcInitArgs pprocInitArgs;
1809
1810 memset(&args, 0, sizeof(DeferWorkArgs));
1811 memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
1812
1813 pprocInitArgs.jpeg_cb = jpegEvtHandle;
1814 pprocInitArgs.user_data = this;
1815 args.pprocInitArgs = pprocInitArgs;
1816
1817 return queueDeferredWork(CMD_DEF_PPROC_INIT,
1818 args);
1819 }
1820
1821 /*===========================================================================
1822 * FUNCTION : openCamera
1823 *
1824 * DESCRIPTION: open camera
1825 *
1826 * PARAMETERS :
1827 * @hw_device : double ptr for camera device struct
1828 *
1829 * RETURN : int32_t type of status
1830 * NO_ERROR -- success
1831 * none-zero failure code
1832 *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1833 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1834 {
1835 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_OPENCAMERA);
1836 int rc = NO_ERROR;
1837 if (mCameraOpened) {
1838 *hw_device = NULL;
1839 LOGE("Permission Denied");
1840 return PERMISSION_DENIED;
1841 }
1842 LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
1843 mCameraId);
1844
1845 m_perfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);
1846
1847 rc = openCamera();
1848 if (rc == NO_ERROR){
1849 *hw_device = &mCameraDevice.common;
1850 if (m_thermalAdapter.init(this) != 0) {
1851 LOGW("Init thermal adapter failed");
1852 }
1853 }
1854 else
1855 *hw_device = NULL;
1856
1857 LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
1858 mCameraId, rc);
1859
1860 return rc;
1861 }
1862
1863 /*===========================================================================
1864 * FUNCTION : openCamera
1865 *
1866 * DESCRIPTION: open camera
1867 *
1868 * PARAMETERS : none
1869 *
1870 * RETURN : int32_t type of status
1871 * NO_ERROR -- success
1872 * none-zero failure code
1873 *==========================================================================*/
openCamera()1874 int QCamera2HardwareInterface::openCamera()
1875 {
1876 int32_t rc = NO_ERROR;
1877 char value[PROPERTY_VALUE_MAX];
1878
1879 if (mCameraHandle) {
1880 LOGE("Failure: Camera already opened");
1881 return ALREADY_EXISTS;
1882 }
1883
1884 rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
1885 if (rc < 0) {
1886 LOGE("Failed to reserve flash for camera id: %d",
1887 mCameraId);
1888 return UNKNOWN_ERROR;
1889 }
1890
1891 // alloc param buffer
1892 DeferWorkArgs args;
1893 memset(&args, 0, sizeof(args));
1894 mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
1895 if (mParamAllocJob == 0) {
1896 LOGE("Failed queueing PARAM_ALLOC job");
1897 return -ENOMEM;
1898 }
1899
1900 if (gCamCapability[mCameraId] != NULL) {
1901 // allocate metadata buffers
1902 DeferWorkArgs args;
1903 DeferMetadataAllocArgs metadataAllocArgs;
1904
1905 memset(&args, 0, sizeof(args));
1906 memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
1907
1908 uint32_t padding =
1909 gCamCapability[mCameraId]->padding_info.plane_padding;
1910 metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
1911 padding);
1912 metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
1913 args.metadataAllocArgs = metadataAllocArgs;
1914
1915 mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
1916 if (mMetadataAllocJob == 0) {
1917 LOGE("Failed to allocate metadata buffer");
1918 rc = -ENOMEM;
1919 goto error_exit1;
1920 }
1921
1922 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1923 if (rc) {
1924 LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1925 rc, mCameraHandle);
1926 goto error_exit2;
1927 }
1928
1929 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1930 camEvtHandle,
1931 (void *) this);
1932 } else {
1933 LOGH("Capabilities not inited, initializing now.");
1934
1935 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1936 if (rc) {
1937 LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1938 rc, mCameraHandle);
1939 goto error_exit2;
1940 }
1941
1942 if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
1943 LOGE("initCapabilities failed.");
1944 rc = UNKNOWN_ERROR;
1945 goto error_exit3;
1946 }
1947
1948 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1949 camEvtHandle,
1950 (void *) this);
1951 }
1952
1953 mActiveCamera = MM_CAMERA_TYPE_MAIN;
1954 if (isDualCamera()) {
1955 mActiveCamera |= MM_CAMERA_TYPE_AUX;
1956
1957 // Create and initialize FOV-control object
1958 m_pFovControl = QCameraFOVControl::create(gCamCapability[mCameraId]->main_cam_cap,
1959 gCamCapability[mCameraId]->aux_cam_cap);
1960 if (m_pFovControl) {
1961 *gCamCapability[mCameraId] = m_pFovControl->consolidateCapabilities(
1962 gCamCapability[mCameraId]->main_cam_cap,
1963 gCamCapability[mCameraId]->aux_cam_cap);
1964 } else {
1965 LOGE("FOV-control: Failed to create an object");
1966 rc = NO_MEMORY;
1967 goto error_exit3;
1968 }
1969 }
1970
1971 // Init params in the background
1972 // 1. It's safe to queue init job, even if alloc job is not yet complete.
1973 // It will be queued to the same thread, so the alloc is guaranteed to
1974 // finish first.
1975 // 2. However, it is not safe to begin param init until after camera is
1976 // open. That is why we wait until after camera open completes to schedule
1977 // this task.
1978 memset(&args, 0, sizeof(args));
1979 mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
1980 if (mParamInitJob == 0) {
1981 LOGE("Failed queuing PARAM_INIT job");
1982 rc = -ENOMEM;
1983 goto error_exit3;
1984 }
1985
1986 mCameraOpened = true;
1987
1988 //Notify display HAL that a camera session is active.
1989 //But avoid calling the same during bootup because camera service might open/close
1990 //cameras at boot time during its initialization and display service will also internally
1991 //wait for camera service to initialize first while calling this display API, resulting in a
1992 //deadlock situation. Since boot time camera open/close calls are made only to fetch
1993 //capabilities, no need of this display bw optimization.
1994 //Use "service.bootanim.exit" property to know boot status.
1995 property_get("service.bootanim.exit", value, "0");
1996 if (atoi(value) == 1) {
1997 pthread_mutex_lock(&gCamLock);
1998 if (gNumCameraSessions++ == 0) {
1999 setCameraLaunchStatus(true);
2000 }
2001 pthread_mutex_unlock(&gCamLock);
2002 }
2003
2004 // Setprop to decide the time source (whether boottime or monotonic).
2005 // By default, use monotonic time.
2006 property_get("persist.camera.time.monotonic", value, "1");
2007 mBootToMonoTimestampOffset = 0;
2008 if (atoi(value) == 1) {
2009 // if monotonic is set, then need to use time in monotonic.
2010 // So, Measure the clock offset between BOOTTIME and MONOTONIC
2011 // The clock domain source for ISP is BOOTTIME and
2012 // for Video/display is MONOTONIC
2013 // The below offset is used to convert from clock domain of other subsystem
2014 // (video/hardware composer) to that of camera. Assumption is that this
2015 // offset won't change during the life cycle of the camera device. In other
2016 // words, camera device shouldn't be open during CPU suspend.
2017 mBootToMonoTimestampOffset = getBootToMonoTimeOffset();
2018 }
2019 LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset);
2020
2021 memset(value, 0, sizeof(value));
2022 property_get("persist.camera.depth.focus.cb", value, "1");
2023 bDepthAFCallbacks = atoi(value);
2024
2025 memset(value, 0, sizeof(value));
2026 property_get("persist.camera.cache.optimize", value, "1");
2027 m_bOptimizeCacheOps = atoi(value);
2028
2029 return NO_ERROR;
2030
2031 error_exit3:
2032 if(mJpegClientHandle) {
2033 deinitJpegHandle();
2034 }
2035 mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2036 mCameraHandle = NULL;
2037 error_exit2:
2038 waitDeferredWork(mMetadataAllocJob);
2039 error_exit1:
2040 waitDeferredWork(mParamAllocJob);
2041 return rc;
2042
2043 }
2044
2045 /*===========================================================================
2046 * FUNCTION : bundleRelatedCameras
2047 *
2048 * DESCRIPTION: bundle cameras to enable syncing of cameras
2049 *
2050 * PARAMETERS :
2051 * @sync :indicates whether syncing is On or Off
2052 *
2053 * RETURN : int32_t type of status
2054 * NO_ERROR -- success
2055 * none-zero failure code
2056 *==========================================================================*/
bundleRelatedCameras(bool syncOn)2057 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn)
2058 {
2059 int32_t rc = mParameters.bundleRelatedCameras(syncOn);
2060 if (rc != NO_ERROR) {
2061 LOGE("bundleRelatedCameras failed %d", rc);
2062 return rc;
2063 }
2064 return rc;
2065 }
2066
2067 /*===========================================================================
2068 * FUNCTION : getCameraSessionId
2069 *
2070 * DESCRIPTION: gets the backend session Id of this HWI instance
2071 *
2072 * PARAMETERS :
2073 * @sessionid : pointer to the output session id
2074 *
2075 * RETURN : int32_t type of status
2076 * NO_ERROR -- success
2077 * none-zero failure code
2078 *==========================================================================*/
getCameraSessionId(uint32_t * session_id)2079 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
2080 {
2081 int32_t rc = NO_ERROR;
2082
2083 if(session_id != NULL) {
2084 rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
2085 session_id);
2086 LOGD("Getting Camera Session Id %d", *session_id);
2087 } else {
2088 LOGE("Session Id is Null");
2089 return UNKNOWN_ERROR;
2090 }
2091 return rc;
2092 }
2093
2094 /*===========================================================================
2095 * FUNCTION : isFrameSyncEnabled
2096 *
2097 * DESCRIPTION: returns whether frame sync is enabled
2098 *
2099 * PARAMETERS : none
2100 *
2101 * RETURN : bool indicating whether frame sync is enabled
2102 *==========================================================================*/
isFrameSyncEnabled(void)2103 bool QCamera2HardwareInterface::isFrameSyncEnabled(void)
2104 {
2105 return mParameters.isFrameSyncEnabled();
2106 }
2107
2108 /*===========================================================================
2109 * FUNCTION : setFrameSyncEnabled
2110 *
2111 * DESCRIPTION: sets whether frame sync is enabled
2112 *
2113 * PARAMETERS :
2114 * @enable : flag whether to enable or disable frame sync
2115 *
2116 * RETURN : int32_t type of status
2117 * NO_ERROR -- success
2118 * none-zero failure code
2119 *==========================================================================*/
setFrameSyncEnabled(bool enable)2120 int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable)
2121 {
2122 return mParameters.setFrameSyncEnabled(enable);
2123 }
2124
2125 /*===========================================================================
2126 * FUNCTION : getRelatedCamSyncInfo
2127 *
2128 * DESCRIPTION:returns the related cam sync info for this HWI instance
2129 *
2130 * PARAMETERS :none
2131 *
2132 * RETURN : const pointer to cam_sync_related_sensors_event_info_t
2133 *==========================================================================*/
2134 const cam_sync_related_sensors_event_info_t*
getRelatedCamSyncInfo(void)2135 QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
2136 {
2137 return mParameters.getRelatedCamSyncInfo();
2138 }
2139
2140 /*===========================================================================
2141 * FUNCTION : setRelatedCamSyncInfo
2142 *
2143 * DESCRIPTION:sets the related cam sync info for this HWI instance
2144 *
2145 * PARAMETERS :
2146 * @info : ptr to related cam info parameters
2147 *
2148 * RETURN : int32_t type of status
2149 * NO_ERROR -- success
2150 * none-zero failure code
2151 *==========================================================================*/
setRelatedCamSyncInfo(cam_sync_related_sensors_event_info_t * info)2152 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
2153 cam_sync_related_sensors_event_info_t* info)
2154 {
2155 if(info) {
2156 return mParameters.setRelatedCamSyncInfo(info);
2157 } else {
2158 return BAD_TYPE;
2159 }
2160 }
2161
2162 /*===========================================================================
2163 * FUNCTION : getMpoComposition
2164 *
2165 * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
2166 * or not
2167 *
2168 * PARAMETERS :none
2169 *
2170 * RETURN : bool indicates whether mpo composition is enabled or not
2171 *==========================================================================*/
getMpoComposition(void)2172 bool QCamera2HardwareInterface::getMpoComposition(void)
2173 {
2174 LOGH("MpoComposition:%d ", m_bMpoEnabled);
2175 return m_bMpoEnabled;
2176 }
2177
2178 /*===========================================================================
2179 * FUNCTION : setMpoComposition
2180 *
2181 * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
2182 *
2183 * PARAMETERS :
2184 * @enable : indicates whether Mpo composition enabled or not
2185 *
2186 * RETURN : int32_t type of status
2187 * NO_ERROR -- success
2188 * none-zero failure code
2189 *==========================================================================*/
setMpoComposition(bool enable)2190 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
2191 {
2192 // By default set Mpo composition to disable
2193 m_bMpoEnabled = false;
2194
2195 // Enable Mpo composition only if
2196 // 1) frame sync is ON between two cameras and
2197 // 2) any advanced features are not enabled (AOST features) and
2198 // 3) not in recording mode (for liveshot case)
2199 // 4) flash is not needed
2200 if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
2201 !mParameters.isAdvCamFeaturesEnabled() &&
2202 !mParameters.getRecordingHintValue() &&
2203 !mFlashNeeded &&
2204 !isLongshotEnabled()) {
2205 m_bMpoEnabled = enable;
2206 LOGH("MpoComposition:%d ", m_bMpoEnabled);
2207 return NO_ERROR;
2208 } else {
2209 return BAD_TYPE;
2210 }
2211 }
2212
2213 /*===========================================================================
2214 * FUNCTION : getRecordingHintValue
2215 *
2216 * DESCRIPTION:function to retrieve recording hint value
2217 *
2218 * PARAMETERS :none
2219 *
2220 * RETURN : bool indicates whether recording hint is enabled or not
2221 *==========================================================================*/
getRecordingHintValue(void)2222 bool QCamera2HardwareInterface::getRecordingHintValue(void)
2223 {
2224 return mParameters.getRecordingHintValue();
2225 }
2226
2227 /*===========================================================================
2228 * FUNCTION : setRecordingHintValue
2229 *
2230 * DESCRIPTION:set recording hint value
2231 *
2232 * PARAMETERS :
2233 * @enable : video hint value
2234 *
2235 * RETURN : int32_t type of status
2236 * NO_ERROR -- success
2237 * none-zero failure code
2238 *==========================================================================*/
setRecordingHintValue(int32_t value)2239 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
2240 {
2241 return mParameters.updateRecordingHintValue(value);
2242 }
2243
2244 /*===========================================================================
2245 * FUNCTION : closeCamera
2246 *
2247 * DESCRIPTION: close camera
2248 *
2249 * PARAMETERS : none
2250 *
2251 * RETURN : int32_t type of status
2252 * NO_ERROR -- success
2253 * none-zero failure code
2254 *==========================================================================*/
closeCamera()2255 int QCamera2HardwareInterface::closeCamera()
2256 {
2257 int rc = NO_ERROR;
2258 int i;
2259 char value[PROPERTY_VALUE_MAX];
2260 LOGI("E");
2261 if (!mCameraOpened) {
2262 return NO_ERROR;
2263 }
2264 LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
2265 mCameraId);
2266
2267 // set open flag to false
2268 mCameraOpened = false;
2269
2270 // Reset Stream config info
2271 mParameters.setStreamConfigure(false, false, true);
2272
2273 // deinit Parameters
2274 mParameters.deinit();
2275
2276 // exit notifier
2277 m_cbNotifier.exit();
2278
2279 // stop and deinit postprocessor
2280 waitDeferredWork(mReprocJob);
2281 // Close the JPEG session
2282 waitDeferredWork(mJpegJob);
2283 m_postprocessor.stop();
2284 deinitJpegHandle();
2285 m_postprocessor.deinit();
2286 mInitPProcJob = 0; // reset job id, so pproc can be reinited later
2287
2288 m_thermalAdapter.deinit();
2289
2290 // delete all channels if not already deleted
2291 for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2292 if (m_channels[i] != NULL) {
2293 m_channels[i]->stop();
2294 delete m_channels[i];
2295 m_channels[i] = NULL;
2296 }
2297 }
2298
2299 //free all pending api results here
2300 if(m_apiResultList != NULL) {
2301 api_result_list *apiResultList = m_apiResultList;
2302 api_result_list *apiResultListNext;
2303 while (apiResultList != NULL) {
2304 apiResultListNext = apiResultList->next;
2305 free(apiResultList);
2306 apiResultList = apiResultListNext;
2307 }
2308 }
2309
2310 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2311 mCameraHandle = NULL;
2312
2313 //Notify display HAL that there is no active camera session
2314 //but avoid calling the same during bootup. Refer to openCamera
2315 //for more details.
2316 property_get("service.bootanim.exit", value, "0");
2317 if (atoi(value) == 1) {
2318 pthread_mutex_lock(&gCamLock);
2319 if (--gNumCameraSessions == 0) {
2320 setCameraLaunchStatus(false);
2321 }
2322 pthread_mutex_unlock(&gCamLock);
2323 }
2324
2325 if (mExifParams.debug_params) {
2326 free(mExifParams.debug_params);
2327 mExifParams.debug_params = NULL;
2328 }
2329
2330 if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
2331 LOGD("Failed to release flash for camera id: %d",
2332 mCameraId);
2333 }
2334
2335 LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
2336 mCameraId, rc);
2337
2338 return rc;
2339 }
2340
2341 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
2342
2343
2344 /*===========================================================================
2345 * FUNCTION : getCapabilities
2346 *
2347 * DESCRIPTION: query camera capability from back-end
2348 *
2349 * PARAMETERS :
2350 * @ops : mm-interface ops structure
2351 * @cam_handle : camera handle for which we need capability
2352 *
2353 * RETURN : ptr type of capability structure
2354 * capability for success
2355 * NULL for failure
2356 *==========================================================================*/
getCapabilities(mm_camera_ops_t * ops,uint32_t cam_handle)2357 cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
2358 uint32_t cam_handle)
2359 {
2360 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2361 int rc = NO_ERROR;
2362 QCameraHeapMemory *capabilityHeap = NULL;
2363 cam_capability_t *cap_ptr = NULL;
2364
2365 if (ops == NULL) {
2366 LOGE("Invalid arguments");
2367 return NULL;
2368 }
2369
2370 capabilityHeap = new QCameraHeapMemory(1);
2371 if (capabilityHeap == NULL) {
2372 LOGE("creation of capabilityHeap failed");
2373 return NULL;
2374 }
2375
2376 /* Allocate memory for capability buffer */
2377 rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
2378 if(rc != OK) {
2379 LOGE("No memory for capability");
2380 goto allocate_failed;
2381 }
2382
2383 /* Map memory for capability buffer */
2384 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
2385
2386 cam_buf_map_type_list bufMapList;
2387 rc = QCameraBufferMaps::makeSingletonBufMapList(
2388 CAM_MAPPING_BUF_TYPE_CAPABILITY,
2389 0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
2390 0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
2391 bufMapList, capabilityHeap->getPtr(0));
2392
2393 if (rc == NO_ERROR) {
2394 rc = ops->map_bufs(cam_handle,
2395 &bufMapList);
2396 }
2397 if(rc < 0) {
2398 LOGE("failed to map capability buffer");
2399 goto map_failed;
2400 }
2401
2402 /* Query Capability */
2403 rc = ops->query_capability(cam_handle);
2404 if(rc < 0) {
2405 LOGE("failed to query capability");
2406 rc = FAILED_TRANSACTION;
2407 goto query_failed;
2408 }
2409
2410 cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
2411 if (cap_ptr == NULL) {
2412 LOGE("out of memory");
2413 rc = NO_MEMORY;
2414 goto query_failed;
2415 }
2416
2417 memset(cap_ptr, 0, sizeof(cam_capability_t));
2418 memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
2419
2420 int index;
2421 for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
2422 cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
2423 p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
2424 p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
2425 }
2426
2427 query_failed:
2428 ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
2429 map_failed:
2430 capabilityHeap->deallocate();
2431 allocate_failed:
2432 delete capabilityHeap;
2433
2434 if (rc != NO_ERROR) {
2435 return NULL;
2436 } else {
2437 return cap_ptr;
2438 }
2439 }
2440
2441 /*===========================================================================
2442 * FUNCTION : initCapabilities
2443 *
2444 * DESCRIPTION: initialize camera capabilities in static data struct
2445 *
2446 * PARAMETERS :
2447 * @cameraId : camera Id
2448 *
2449 * RETURN : int32_t type of status
2450 * NO_ERROR -- success
2451 * none-zero failure code
2452 *==========================================================================*/
initCapabilities(uint32_t cameraId,mm_camera_vtbl_t * cameraHandle)2453 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
2454 mm_camera_vtbl_t *cameraHandle)
2455 {
2456 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_INIT_CAP);
2457 int rc = 0;
2458 uint32_t handle = 0;
2459
2460 rc = camera_open((uint8_t)cameraId, &cameraHandle);
2461 if (rc) {
2462 LOGE("camera_open failed. rc = %d", rc);
2463 goto open_failed;
2464 }
2465 if (!cameraHandle) {
2466 LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
2467 goto open_failed;
2468 }
2469
2470 handle = get_main_camera_handle(cameraHandle->camera_handle);
2471 gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
2472 if (gCamCapability[cameraId] == NULL) {
2473 rc = FAILED_TRANSACTION;
2474 goto failed_op;
2475 }
2476
2477 gCamCapability[cameraId]->camera_index = cameraId;
2478 if (is_dual_camera_by_idx(cameraId)) {
2479 handle = get_aux_camera_handle(cameraHandle->camera_handle);
2480 gCamCapability[cameraId]->aux_cam_cap =
2481 getCapabilities(cameraHandle->ops, handle);
2482 if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
2483 rc = FAILED_TRANSACTION;
2484 free(gCamCapability[cameraId]);
2485 goto failed_op;
2486 }
2487
2488 // Copy the main camera capability to main_cam_cap struct
2489 gCamCapability[cameraId]->main_cam_cap =
2490 (cam_capability_t *)malloc(sizeof(cam_capability_t));
2491 if (gCamCapability[cameraId]->main_cam_cap == NULL) {
2492 LOGE("out of memory");
2493 rc = NO_MEMORY;
2494 goto failed_op;
2495 }
2496 memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId],
2497 sizeof(cam_capability_t));
2498 }
2499 failed_op:
2500 cameraHandle->ops->close_camera(cameraHandle->camera_handle);
2501 cameraHandle = NULL;
2502 open_failed:
2503 return rc;
2504 }
2505
2506 /*===========================================================================
2507 * FUNCTION : getCapabilities
2508 *
2509 * DESCRIPTION: query camera capabilities
2510 *
2511 * PARAMETERS :
2512 * @cameraId : camera Id
2513 * @info : camera info struct to be filled in with camera capabilities
2514 *
2515 * RETURN : int type of status
2516 * NO_ERROR -- success
2517 * none-zero failure code
2518 *==========================================================================*/
getCapabilities(uint32_t cameraId,struct camera_info * info,cam_sync_type_t * p_cam_type)2519 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
2520 struct camera_info *info, cam_sync_type_t *p_cam_type)
2521 {
2522 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2523 int rc = NO_ERROR;
2524 struct camera_info *p_info = NULL;
2525 pthread_mutex_lock(&gCamLock);
2526 p_info = get_cam_info(cameraId, p_cam_type);
2527 p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
2528 p_info->static_camera_characteristics = NULL;
2529 memcpy(info, p_info, sizeof (struct camera_info));
2530 pthread_mutex_unlock(&gCamLock);
2531 return rc;
2532 }
2533
2534 /*===========================================================================
2535 * FUNCTION : getCamHalCapabilities
2536 *
2537 * DESCRIPTION: get the HAL capabilities structure
2538 *
2539 * PARAMETERS :
2540 * @cameraId : camera Id
2541 *
2542 * RETURN : capability structure of respective camera
2543 *
2544 *==========================================================================*/
getCamHalCapabilities()2545 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
2546 {
2547 return gCamCapability[mCameraId];
2548 }
2549
2550 /*===========================================================================
2551 * FUNCTION : getBufNumForAux
2552 *
2553 * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
2554 *
2555 * PARAMETERS :
2556 * @stream_type : type of stream
2557 *
2558 * RETURN : number of buffers needed
2559 * NOTE : Based on the use cases and auxillary camera type,
2560 we can decide buffer count
2561 *==========================================================================*/
getBufNumForAux(cam_stream_type_t stream_type)2562 uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
2563 {
2564 if (!isDualCamera()) {
2565 return 0;
2566 }
2567
2568 uint8_t bufferCnt = 1;
2569 switch (stream_type) {
2570 case CAM_STREAM_TYPE_PREVIEW:
2571 case CAM_STREAM_TYPE_VIDEO:
2572 case CAM_STREAM_TYPE_SNAPSHOT:
2573 case CAM_STREAM_TYPE_METADATA:
2574 case CAM_STREAM_TYPE_CALLBACK:
2575 case CAM_STREAM_TYPE_ANALYSIS:
2576 case CAM_STREAM_TYPE_POSTVIEW:
2577 case CAM_STREAM_TYPE_RAW:
2578 case CAM_STREAM_TYPE_OFFLINE_PROC:
2579 case CAM_STREAM_TYPE_DEFAULT:
2580 case CAM_STREAM_TYPE_MAX:
2581 //For wide & tele, we use same buffer count premary and aux streams.
2582 bufferCnt = getBufNumRequired(stream_type);
2583 break;
2584 default:
2585 break;
2586 }
2587 LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
2588 return bufferCnt;
2589 }
2590
2591 /*===========================================================================
2592 * FUNCTION : getBufNumRequired
2593 *
2594 * DESCRIPTION: return number of stream buffers needed for given stream type
2595 *
2596 * PARAMETERS :
2597 * @stream_type : type of stream
2598 *
2599 * RETURN : number of buffers needed
2600 *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)2601 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
2602 {
2603 int bufferCnt = 0;
2604 int minCaptureBuffers = mParameters.getNumOfSnapshots();
2605 char value[PROPERTY_VALUE_MAX];
2606 bool raw_yuv = false;
2607 int persist_cnt = 0;
2608 int minPrevFps, maxPrevFps;
2609
2610 int zslQBuffers = mParameters.getZSLQueueDepth();
2611
2612 int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
2613 CAMERA_MIN_JPEG_ENCODING_BUFFERS;
2614
2615 int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
2616 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2617 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2618 mParameters.getNumOfExtraBuffersForImageProc() +
2619 EXTRA_ZSL_PREVIEW_STREAM_BUF;
2620
2621 int minUndequeCount = 0;
2622 if (!isNoDisplayMode()) {
2623 if(mPreviewWindow != NULL) {
2624 if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
2625 != 0) {
2626 LOGW("get_min_undequeued_buffer_count failed");
2627 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
2628 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2629 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2630 }
2631 } else {
2632 //preview window might not be set at this point. So, query directly
2633 //from BufferQueue implementation of gralloc buffers.
2634 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2635 //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
2636 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2637 }
2638 if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
2639 // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
2640 // and so change the MACRO as per minUndequeCount
2641 LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
2642 minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
2643 }
2644 }
2645
2646 LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
2647 "maxStreamBuf = %d minUndequeCount = %d",
2648 minCaptureBuffers, zslQBuffers, minCircularBufNum,
2649 maxStreamBuf, minUndequeCount);
2650 // Get buffer count for the particular stream type
2651 switch (stream_type) {
2652 case CAM_STREAM_TYPE_PREVIEW:
2653 {
2654 if (mParameters.isZSLMode()) {
2655 // We need to add two extra streming buffers to add
2656 // flexibility in forming matched super buf in ZSL queue.
2657 // with number being 'zslQBuffers + minCircularBufNum'
2658 // we see preview buffers sometimes get dropped at CPP
2659 // and super buf is not forming in ZSL Q for long time.
2660
2661 bufferCnt = zslQBuffers + minCircularBufNum +
2662 mParameters.getNumOfExtraBuffersForImageProc() +
2663 mParameters.getNumOfExtraBuffersForPreview() +
2664 mParameters.getNumOfExtraHDRInBufsIfNeeded();
2665 } else {
2666 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
2667 mParameters.getMaxUnmatchedFramesInQueue() +
2668 mParameters.getNumOfExtraBuffersForPreview();
2669 }
2670 // ISP allocates native preview buffers and so reducing same from HAL allocation
2671 if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
2672 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2673
2674 // Extra ZSL preview frames are not needed for HFR case.
2675 // Thumbnail will not be derived from preview for HFR live snapshot case.
2676 if ((mParameters.getRecordingHintValue() == true)
2677 && (!mParameters.isHfrMode())) {
2678 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
2679 }
2680 //Adding Extra preview buffers for 60FPS usecase.
2681 mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
2682 if (maxPrevFps > CAMERA_DEFAULT_FPS) {
2683 bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
2684 }
2685
2686 // Add the display minUndequeCount count on top of camera requirement
2687 bufferCnt += minUndequeCount;
2688
2689 property_get("persist.camera.preview_yuv", value, "0");
2690 persist_cnt = atoi(value);
2691 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2692 && (bufferCnt < persist_cnt)) {
2693 bufferCnt = persist_cnt;
2694 }
2695 }
2696 break;
2697 case CAM_STREAM_TYPE_POSTVIEW:
2698 {
2699 bufferCnt = minCaptureBuffers +
2700 mParameters.getMaxUnmatchedFramesInQueue() +
2701 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2702 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2703 mParameters.getNumOfExtraBuffersForImageProc();
2704
2705 if (bufferCnt > maxStreamBuf) {
2706 bufferCnt = maxStreamBuf;
2707 }
2708 bufferCnt += minUndequeCount;
2709 }
2710 break;
2711 case CAM_STREAM_TYPE_SNAPSHOT:
2712 {
2713 if (mParameters.isZSLMode() || mLongshotEnabled) {
2714 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
2715 !mLongshotEnabled) {
2716 // Single ZSL snapshot case
2717 bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
2718 mParameters.getNumOfExtraBuffersForImageProc();
2719 }
2720 else {
2721 // ZSL Burst or Longshot case
2722 bufferCnt = zslQBuffers + minCircularBufNum +
2723 mParameters.getNumOfExtraBuffersForImageProc();
2724 }
2725 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2726 //ISP allocates native buffers in YUV case
2727 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2728 }
2729 } else {
2730 bufferCnt = minCaptureBuffers +
2731 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2732 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2733 mParameters.getNumOfExtraBuffersForImageProc();
2734
2735 if (bufferCnt > maxStreamBuf) {
2736 bufferCnt = maxStreamBuf;
2737 }
2738 }
2739 }
2740 break;
2741 case CAM_STREAM_TYPE_RAW:
2742 property_get("persist.camera.raw_yuv", value, "0");
2743 raw_yuv = atoi(value) > 0 ? true : false;
2744
2745 if (isRdiMode() || raw_yuv) {
2746 bufferCnt = zslQBuffers + minCircularBufNum;
2747 } else if (mParameters.isZSLMode()) {
2748 bufferCnt = zslQBuffers + minCircularBufNum;
2749 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2750 //ISP allocates native buffers in YUV case
2751 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2752 }
2753
2754 } else {
2755 bufferCnt = minCaptureBuffers +
2756 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2757 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2758 mParameters.getNumOfExtraBuffersForImageProc();
2759
2760 if (bufferCnt > maxStreamBuf) {
2761 bufferCnt = maxStreamBuf;
2762 }
2763 }
2764
2765 property_get("persist.camera.preview_raw", value, "0");
2766 persist_cnt = atoi(value);
2767 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2768 && (bufferCnt < persist_cnt)) {
2769 bufferCnt = persist_cnt;
2770 }
2771 property_get("persist.camera.video_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
2778 break;
2779 case CAM_STREAM_TYPE_VIDEO:
2780 {
2781 if (mParameters.getBufBatchCount()) {
2782 //Video Buffer in case of HFR or camera batching..
2783 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
2784 } else if (mParameters.getVideoBatchSize()) {
2785 //Video Buffer count only for HAL to HAL batching.
2786 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
2787 * mParameters.getVideoBatchSize());
2788 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
2789 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2790 }
2791 } else {
2792 // No batching enabled.
2793 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2794 }
2795
2796 bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
2797 //if its 4K encoding usecase, then add extra buffer
2798 cam_dimension_t dim;
2799 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
2800 if (is4k2kResolution(&dim)) {
2801 //get additional buffer count
2802 property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
2803 bufferCnt += atoi(value);
2804 }
2805 }
2806 break;
2807 case CAM_STREAM_TYPE_METADATA:
2808 {
2809 if (mParameters.isZSLMode()) {
2810 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
2811 bufferCnt = zslQBuffers + minCircularBufNum +
2812 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2813 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2814 mParameters.getNumOfExtraBuffersForImageProc() +
2815 EXTRA_ZSL_PREVIEW_STREAM_BUF;
2816 } else {
2817 bufferCnt = minCaptureBuffers +
2818 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2819 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2820 mParameters.getMaxUnmatchedFramesInQueue() +
2821 CAMERA_MIN_STREAMING_BUFFERS +
2822 mParameters.getNumOfExtraBuffersForImageProc();
2823
2824 if (bufferCnt > zslQBuffers + minCircularBufNum) {
2825 bufferCnt = zslQBuffers + minCircularBufNum;
2826 }
2827 }
2828 if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
2829 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
2830 }
2831 }
2832 break;
2833 case CAM_STREAM_TYPE_OFFLINE_PROC:
2834 {
2835 bufferCnt = minCaptureBuffers;
2836 // One of the ubifocus buffers is miscellaneous buffer
2837 if (mParameters.isUbiRefocus()) {
2838 bufferCnt -= 1;
2839 }
2840 if (mLongshotEnabled) {
2841 bufferCnt = mParameters.getLongshotStages();
2842 }
2843 }
2844 break;
2845 case CAM_STREAM_TYPE_CALLBACK:
2846 bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
2847 break;
2848 case CAM_STREAM_TYPE_ANALYSIS:
2849 case CAM_STREAM_TYPE_DEFAULT:
2850 case CAM_STREAM_TYPE_MAX:
2851 default:
2852 bufferCnt = 0;
2853 break;
2854 }
2855
2856 LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
2857 if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
2858 LOGW("Buffer count %d for stream type %d exceeds limit %d",
2859 bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
2860 return CAM_MAX_NUM_BUFS_PER_STREAM;
2861 }
2862
2863 return (uint8_t)bufferCnt;
2864 }
2865
2866 /*===========================================================================
2867 * FUNCTION : getStreamRefCount
2868 *
2869 * DESCRIPTION: return number of instance of stream of stream type
2870 *
2871 * PARAMETERS :
2872 * @stream_type : type of stream
2873 *
2874 * RETURN : number of stream instances
2875 * NOTE : Based on the use cases and auxillary camera type,
2876 we can decide stream reference count.
2877 For example in wide and tele use case, we duplicate all stream
2878 streams from premary to auxillary.
2879 *==========================================================================*/
getStreamRefCount(cam_stream_type_t stream_type)2880 uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type)
2881 {
2882 uint8_t ref_cnt = 1;
2883 switch (stream_type) {
2884 case CAM_STREAM_TYPE_PREVIEW:
2885 case CAM_STREAM_TYPE_SNAPSHOT:
2886 case CAM_STREAM_TYPE_VIDEO:
2887 case CAM_STREAM_TYPE_METADATA:
2888 case CAM_STREAM_TYPE_ANALYSIS:
2889 case CAM_STREAM_TYPE_CALLBACK:
2890 if (isDualCamera()) {
2891 ref_cnt++;
2892 }
2893 break;
2894 case CAM_STREAM_TYPE_POSTVIEW:
2895 case CAM_STREAM_TYPE_RAW:
2896 case CAM_STREAM_TYPE_OFFLINE_PROC:
2897 case CAM_STREAM_TYPE_DEFAULT:
2898 case CAM_STREAM_TYPE_MAX:
2899 default:
2900 break;
2901 }
2902 return ref_cnt;
2903 }
2904
2905 /*===========================================================================
2906 * FUNCTION : getCamHandleForChannel
2907 *
2908 * DESCRIPTION: return actual camera handle based on use case
2909 *
2910 * PARAMETERS :
2911 * @ch_type : type of channel
2912 *
2913 * RETURN : uint32_t type camera handle
2914 * NOTE : Based on the use cases and auxillary camera type, we can decide cam handle for channel.
2915 Incase, we want to avoid any channel for auxillary camera, we can decide here
2916 *==========================================================================*/
getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)2917 uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
2918 {
2919 uint32_t handle = 0;
2920 if (!isDualCamera()) {
2921 return mCameraHandle->camera_handle;
2922 }
2923
2924 /*Based on the use case, decide camera handle for channel*/
2925 switch (ch_type) {
2926 case QCAMERA_CH_TYPE_ZSL:
2927 case QCAMERA_CH_TYPE_CAPTURE:
2928 case QCAMERA_CH_TYPE_PREVIEW:
2929 case QCAMERA_CH_TYPE_VIDEO:
2930 case QCAMERA_CH_TYPE_SNAPSHOT:
2931 case QCAMERA_CH_TYPE_RAW:
2932 case QCAMERA_CH_TYPE_METADATA:
2933 case QCAMERA_CH_TYPE_ANALYSIS:
2934 case QCAMERA_CH_TYPE_CALLBACK:
2935 case QCAMERA_CH_TYPE_MAX:
2936 default:
2937 handle = mCameraHandle->camera_handle;
2938 break;
2939 case QCAMERA_CH_TYPE_REPROCESSING:
2940 handle = get_main_camera_handle(mCameraHandle->camera_handle);
2941 break;
2942 }
2943 return handle;
2944 }
2945
2946 /*===========================================================================
2947 * FUNCTION : allocateStreamBuf
2948 *
2949 * DESCRIPTION: alocate stream buffers
2950 *
2951 * PARAMETERS :
2952 * @stream_type : type of stream
2953 * @size : size of buffer
2954 * @stride : stride of buffer
2955 * @scanline : scanline of buffer
2956 * @bufferCnt : [IN/OUT] minimum num of buffers to be allocated.
2957 * could be modified during allocation if more buffers needed
2958 *
2959 * RETURN : ptr to a memory obj that holds stream buffers.
2960 * NULL if failed
2961 *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,size_t size,int stride,int scanline,uint8_t & bufferCnt)2962 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
2963 cam_stream_type_t stream_type, size_t size, int stride, int scanline,
2964 uint8_t &bufferCnt)
2965 {
2966 int rc = NO_ERROR;
2967 QCameraMemory *mem = NULL;
2968 bool bCachedMem = QCAMERA_ION_USE_CACHE;
2969 bool bPoolMem = false;
2970 char value[PROPERTY_VALUE_MAX];
2971 property_get("persist.camera.mem.usepool", value, "1");
2972 if (atoi(value) == 1) {
2973 bPoolMem = true;
2974 }
2975
2976 // Allocate stream buffer memory object
2977 switch (stream_type) {
2978 case CAM_STREAM_TYPE_PREVIEW:
2979 {
2980 if (isNoDisplayMode()) {
2981 mem = new QCameraStreamMemory(mGetMemory,
2982 bCachedMem,
2983 (bPoolMem) ? &m_memoryPool : NULL,
2984 stream_type);
2985 } else {
2986 cam_dimension_t dim;
2987 int minFPS, maxFPS;
2988 QCameraGrallocMemory *grallocMemory =
2989 new QCameraGrallocMemory(mGetMemory);
2990
2991 mParameters.getStreamDimension(stream_type, dim);
2992 /* we are interested only in maxfps here */
2993 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
2994 int usage = 0;
2995 if(mParameters.isUBWCEnabled()) {
2996 cam_format_t fmt;
2997 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
2998 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
2999 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
3000 }
3001 }
3002 if (grallocMemory) {
3003 grallocMemory->setMappable(
3004 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3005 grallocMemory->setWindowInfo(mPreviewWindow,
3006 dim.width,dim.height, stride, scanline,
3007 mParameters.getPreviewHalPixelFormat(),
3008 maxFPS, usage);
3009 pthread_mutex_lock(&mGrallocLock);
3010 if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
3011 mEnqueuedBuffers = (bufferCnt -
3012 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3013 } else {
3014 mEnqueuedBuffers = 0;
3015 }
3016 pthread_mutex_unlock(&mGrallocLock);
3017 }
3018 mem = grallocMemory;
3019 }
3020 }
3021 break;
3022 case CAM_STREAM_TYPE_POSTVIEW:
3023 {
3024 if (isNoDisplayMode() || isPreviewRestartEnabled()) {
3025 mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
3026 } else {
3027 cam_dimension_t dim;
3028 int minFPS, maxFPS;
3029 QCameraGrallocMemory *grallocMemory =
3030 new QCameraGrallocMemory(mGetMemory);
3031
3032 mParameters.getStreamDimension(stream_type, dim);
3033 /* we are interested only in maxfps here */
3034 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3035 if (grallocMemory) {
3036 grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
3037 dim.height, stride, scanline,
3038 mParameters.getPreviewHalPixelFormat(), maxFPS);
3039 }
3040 mem = grallocMemory;
3041 }
3042 }
3043 break;
3044 case CAM_STREAM_TYPE_ANALYSIS:
3045 case CAM_STREAM_TYPE_SNAPSHOT:
3046 case CAM_STREAM_TYPE_RAW:
3047 case CAM_STREAM_TYPE_OFFLINE_PROC:
3048 mem = new QCameraStreamMemory(mGetMemory,
3049 bCachedMem,
3050 (bPoolMem) ? &m_memoryPool : NULL,
3051 stream_type);
3052 break;
3053 case CAM_STREAM_TYPE_METADATA:
3054 {
3055 if (mMetadataMem == NULL) {
3056 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
3057 } else {
3058 mem = mMetadataMem;
3059 mMetadataMem = NULL;
3060
3061 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
3062 if (numAdditionalBuffers > 0) {
3063 rc = mem->allocateMore(numAdditionalBuffers, size);
3064 if (rc != NO_ERROR) {
3065 LOGE("Failed to allocate additional buffers, "
3066 "but attempting to proceed.");
3067 }
3068 }
3069 bufferCnt = mem->getCnt();
3070 // The memory is already allocated and initialized, so
3071 // simply return here.
3072 return mem;
3073 }
3074 }
3075 break;
3076 case CAM_STREAM_TYPE_VIDEO:
3077 {
3078 //Use uncached allocation by default
3079 if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
3080 mParameters.isHighQualityNoiseReductionMode()) {
3081 bCachedMem = QCAMERA_ION_USE_CACHE;
3082 }
3083 else {
3084 bCachedMem = QCAMERA_ION_USE_NOCACHE;
3085 }
3086
3087 QCameraVideoMemory *videoMemory = NULL;
3088 if (mParameters.getVideoBatchSize()) {
3089 videoMemory = new QCameraVideoMemory(
3090 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
3091 if (videoMemory == NULL) {
3092 LOGE("Out of memory for video batching obj");
3093 return NULL;
3094 }
3095 /*
3096 * numFDs = BATCH size
3097 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3098 */
3099 rc = videoMemory->allocateMeta(
3100 CAMERA_MIN_VIDEO_BATCH_BUFFERS,
3101 mParameters.getVideoBatchSize(),
3102 VIDEO_METADATA_NUM_INTS);
3103 if (rc < 0) {
3104 delete videoMemory;
3105 return NULL;
3106 }
3107 } else {
3108 videoMemory =
3109 new QCameraVideoMemory(mGetMemory, bCachedMem);
3110 if (videoMemory == NULL) {
3111 LOGE("Out of memory for video obj");
3112 return NULL;
3113 }
3114 }
3115
3116 int usage = 0;
3117 cam_format_t fmt;
3118 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
3119 if (mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3120 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3121 }
3122 videoMemory->setVideoInfo(usage, fmt);
3123 mem = videoMemory;
3124 }
3125 break;
3126 case CAM_STREAM_TYPE_CALLBACK:
3127 mem = new QCameraStreamMemory(mGetMemory,
3128 bCachedMem,
3129 (bPoolMem) ? &m_memoryPool : NULL,
3130 stream_type);
3131 break;
3132 case CAM_STREAM_TYPE_DEFAULT:
3133 case CAM_STREAM_TYPE_MAX:
3134 default:
3135 break;
3136 }
3137 if (!mem) {
3138 return NULL;
3139 }
3140
3141 if (bufferCnt > 0) {
3142 if (mParameters.isSecureMode() &&
3143 (stream_type == CAM_STREAM_TYPE_RAW) &&
3144 (mParameters.isRdiMode())) {
3145 LOGD("Allocating %d secure buffers of size %d ", bufferCnt, size);
3146 rc = mem->allocate(bufferCnt, size, SECURE);
3147 } else {
3148 rc = mem->allocate(bufferCnt, size, NON_SECURE);
3149 }
3150 if (rc < 0) {
3151 delete mem;
3152 return NULL;
3153 }
3154 bufferCnt = mem->getCnt();
3155 }
3156 LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d mEnqueuedBuffers = %d",
3157 rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem, mEnqueuedBuffers);
3158 return mem;
3159 }
3160
3161 /*===========================================================================
3162 * FUNCTION : allocateMoreStreamBuf
3163 *
3164 * DESCRIPTION: alocate more stream buffers from the memory object
3165 *
3166 * PARAMETERS :
3167 * @mem_obj : memory object ptr
3168 * @size : size of buffer
3169 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated.
3170 * output will be the number of total buffers
3171 *
3172 * RETURN : int32_t type of status
3173 * NO_ERROR -- success
3174 * none-zero failure code
3175 *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,size_t size,uint8_t & bufferCnt)3176 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
3177 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
3178 {
3179 int rc = NO_ERROR;
3180
3181 if (bufferCnt > 0) {
3182 rc = mem_obj->allocateMore(bufferCnt, size);
3183 bufferCnt = mem_obj->getCnt();
3184 }
3185 return rc;
3186 }
3187
3188 /*===========================================================================
3189 * FUNCTION : allocateMiscBuf
3190 *
3191 * DESCRIPTION: alocate miscellaneous buffer
3192 *
3193 * PARAMETERS :
3194 * @streamInfo : stream info
3195 *
3196 * RETURN : ptr to a memory obj that holds stream info buffer.
3197 * NULL if failed
3198 *==========================================================================*/
allocateMiscBuf(cam_stream_info_t * streamInfo)3199 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
3200 cam_stream_info_t *streamInfo)
3201 {
3202 int rc = NO_ERROR;
3203 uint8_t bufNum = 0;
3204 size_t bufSize = 0;
3205 QCameraHeapMemory *miscBuf = NULL;
3206 cam_feature_mask_t feature_mask =
3207 streamInfo->reprocess_config.pp_feature_config.feature_mask;
3208
3209 switch (streamInfo->stream_type) {
3210 case CAM_STREAM_TYPE_OFFLINE_PROC:
3211 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
3212 bufNum = 1;
3213 bufSize = mParameters.getTPMaxMetaSize();
3214 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
3215 bufNum = 1;
3216 bufSize = mParameters.getRefocusMaxMetaSize();
3217 }
3218 break;
3219 default:
3220 break;
3221 }
3222
3223 if (bufNum && bufSize) {
3224 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3225
3226 if (!miscBuf) {
3227 LOGE("Unable to allocate miscBuf object");
3228 return NULL;
3229 }
3230
3231 rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE);
3232 if (rc < 0) {
3233 LOGE("Failed to allocate misc buffer memory");
3234 delete miscBuf;
3235 return NULL;
3236 }
3237 }
3238
3239 return miscBuf;
3240 }
3241
3242 /*===========================================================================
3243 * FUNCTION : initStreamInfoBuf
3244 *
3245 * DESCRIPTION: initialize stream info buffer based on stream type
3246 *
3247 * PARAMETERS :
3248 * @stream_type : type of stream
3249 *
3250 * RETURN : ptr to a memory obj that holds stream info buffer.
3251 * NULL if failed
3252 *==========================================================================*/
initStreamInfoBuf(cam_stream_type_t stream_type,cam_stream_info_t * streamInfo)3253 int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
3254 cam_stream_info_t *streamInfo)
3255 {
3256 int rc = NO_ERROR;
3257 int32_t dt = 0;
3258 int32_t vc = 0;
3259
3260 memset(streamInfo, 0, sizeof(cam_stream_info_t));
3261 streamInfo->stream_type = stream_type;
3262 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
3263 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
3264 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
3265 streamInfo->num_bufs = getBufNumRequired(stream_type);
3266 streamInfo->buf_cnt = streamInfo->num_bufs;
3267 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3268 streamInfo->is_secure = NON_SECURE;
3269 // Initialize cache ops
3270 if (!m_bOptimizeCacheOps) {
3271 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_DISABLED;
3272 } else {
3273 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_HONOUR_FLAGS;
3274 }
3275
3276 switch (stream_type) {
3277 case CAM_STREAM_TYPE_SNAPSHOT:
3278 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
3279 mLongshotEnabled) {
3280 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3281 } else {
3282 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3283 streamInfo->num_of_burst = (uint8_t)
3284 (mParameters.getNumOfSnapshots()
3285 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3286 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3287 + mParameters.getNumOfExtraBuffersForImageProc());
3288 }
3289 break;
3290 case CAM_STREAM_TYPE_RAW: {
3291 char value[PROPERTY_VALUE_MAX];
3292 bool raw_yuv = false;
3293 property_get("persist.camera.raw_yuv", value, "0");
3294 raw_yuv = atoi(value) > 0 ? true : false;
3295 if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) {
3296 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3297 } else {
3298 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3299 streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
3300 }
3301 if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
3302 streamInfo->is_secure = SECURE;
3303 } else {
3304 streamInfo->is_secure = NON_SECURE;
3305 }
3306 }
3307 if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
3308 mParameters.updateDtVc(&dt, &vc);
3309 if (dt)
3310 streamInfo->dt = dt;
3311 streamInfo->vc = vc;
3312 }
3313
3314 break;
3315 case CAM_STREAM_TYPE_POSTVIEW:
3316 if (mLongshotEnabled) {
3317 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3318 } else {
3319 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3320 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
3321 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3322 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3323 + mParameters.getNumOfExtraBuffersForImageProc());
3324 }
3325 break;
3326 case CAM_STREAM_TYPE_VIDEO:
3327 streamInfo->dis_enable = mParameters.isDISEnabled();
3328 if (mParameters.getBufBatchCount()) {
3329 //Update stream info structure with batch mode info
3330 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
3331 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
3332 streamInfo->user_buf_info.size =
3333 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
3334 cam_fps_range_t pFpsRange;
3335 mParameters.getHfrFps(pFpsRange);
3336 streamInfo->user_buf_info.frameInterval =
3337 (long)((1000/pFpsRange.video_max_fps) * 1000);
3338 LOGH("Video Batch Count = %d, interval = %d",
3339 streamInfo->user_buf_info.frame_buf_cnt,
3340 streamInfo->user_buf_info.frameInterval);
3341 }
3342 if (mParameters.getRecordingHintValue()) {
3343 if(mParameters.isDISEnabled()) {
3344 streamInfo->is_type = mParameters.getVideoISType();
3345 } else {
3346 streamInfo->is_type = IS_TYPE_NONE;
3347 }
3348 }
3349 if (mParameters.isSecureMode()) {
3350 streamInfo->is_secure = SECURE;
3351 }
3352 break;
3353 case CAM_STREAM_TYPE_PREVIEW:
3354 if (mParameters.getRecordingHintValue()) {
3355 if(mParameters.isDISEnabled()) {
3356 streamInfo->is_type = mParameters.getPreviewISType();
3357 } else {
3358 streamInfo->is_type = IS_TYPE_NONE;
3359 }
3360 }
3361 if (mParameters.isSecureMode()) {
3362 streamInfo->is_secure = SECURE;
3363 }
3364 break;
3365 case CAM_STREAM_TYPE_ANALYSIS:
3366 streamInfo->noFrameExpected = 1;
3367 break;
3368 case CAM_STREAM_TYPE_METADATA:
3369 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_CLEAR_FLAGS;
3370 break;
3371 default:
3372 break;
3373 }
3374
3375 // Update feature mask
3376 mParameters.updatePpFeatureMask(stream_type);
3377
3378 // Get feature mask
3379 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
3380
3381 // Update pp config
3382 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
3383 int flipMode = mParameters.getFlipMode(stream_type);
3384 if (flipMode > 0) {
3385 streamInfo->pp_config.flip = (uint32_t)flipMode;
3386 }
3387 }
3388 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3389 streamInfo->pp_config.sharpness = mParameters.getSharpness();
3390 }
3391 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
3392 streamInfo->pp_config.effect = mParameters.getEffectValue();
3393 }
3394
3395 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
3396 streamInfo->pp_config.denoise2d.denoise_enable = 1;
3397 streamInfo->pp_config.denoise2d.process_plates =
3398 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
3399 }
3400
3401 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
3402 CAM_STREAM_TYPE_RAW == stream_type))) {
3403 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3404 CAM_QCOM_FEATURE_CROP)
3405 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
3406 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3407 CAM_QCOM_FEATURE_SCALE)
3408 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
3409 }
3410 streamInfo->aux_str_info = NULL;
3411
3412 LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
3413 stream_type, streamInfo->fmt, streamInfo->dim.width,
3414 streamInfo->dim.height, streamInfo->num_bufs,
3415 streamInfo->pp_config.feature_mask,
3416 streamInfo->is_type);
3417
3418 return rc;
3419 }
3420
3421 /*===========================================================================
3422 * FUNCTION : allocateStreamInfoBuf
3423 *
3424 * DESCRIPTION: alocate stream info buffer
3425 *
3426 * PARAMETERS :
3427 * @stream_type : type of stream
3428 * @bufCount : stream info buffer count
3429 *
3430 * RETURN : ptr to a memory obj that holds stream info buffer.
3431 * NULL if failed
3432 *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type,uint8_t bufCount)3433 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
3434 cam_stream_type_t stream_type, uint8_t bufCount)
3435 {
3436 int rc = NO_ERROR;
3437
3438 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3439 if (!streamInfoBuf) {
3440 LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
3441 return NULL;
3442 }
3443
3444 if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
3445 LOGE("buffer count should be lesser than max camera : %d", bufCount);
3446 return NULL;
3447 }
3448 rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t), NON_SECURE);
3449 if (rc < 0) {
3450 LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
3451 delete streamInfoBuf;
3452 return NULL;
3453 }
3454
3455 for (uint8_t i = 0; i < bufCount; i++) {
3456 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
3457 memset(streamInfo, 0, sizeof(cam_stream_info_t));
3458 rc = initStreamInfoBuf(stream_type, streamInfo);
3459 if (rc < 0) {
3460 LOGE("initStreamInfoBuf failed");
3461 delete streamInfoBuf;
3462 return NULL;
3463 }
3464 }
3465
3466 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
3467 if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
3468 cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
3469 streamInfo->aux_str_info = s_streamInfo;
3470 }
3471
3472 if (streamInfo->aux_str_info != NULL) {
3473 /*Update StreamInfo for Aux camera*/
3474 streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
3475 streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
3476 streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
3477 }
3478 return streamInfoBuf;
3479 }
3480
3481 /*===========================================================================
3482 * FUNCTION : allocateStreamUserBuf
3483 *
3484 * DESCRIPTION: allocate user ptr for stream buffers
3485 *
3486 * PARAMETERS :
3487 * @streamInfo : stream info structure
3488 *
3489 * RETURN : ptr to a memory obj that holds stream info buffer.
3490 * NULL if failed
3491
3492 *==========================================================================*/
allocateStreamUserBuf(cam_stream_info_t * streamInfo)3493 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
3494 cam_stream_info_t *streamInfo)
3495 {
3496 int rc = NO_ERROR;
3497 QCameraMemory *mem = NULL;
3498 int size = 0;
3499
3500 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
3501 LOGE("Stream is not in BATCH mode. Invalid Stream");
3502 return NULL;
3503 }
3504
3505 // Allocate stream user buffer memory object
3506 switch (streamInfo->stream_type) {
3507 case CAM_STREAM_TYPE_VIDEO: {
3508 QCameraVideoMemory *video_mem = new QCameraVideoMemory(
3509 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
3510 if (video_mem == NULL) {
3511 LOGE("Out of memory for video obj");
3512 return NULL;
3513 }
3514 /*
3515 * numFDs = BATCH size
3516 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3517 */
3518 rc = video_mem->allocateMeta(streamInfo->num_bufs,
3519 mParameters.getBufBatchCount(), VIDEO_METADATA_NUM_INTS);
3520 if (rc < 0) {
3521 LOGE("allocateMeta failed");
3522 delete video_mem;
3523 return NULL;
3524 }
3525 int usage = 0;
3526 cam_format_t fmt;
3527 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
3528 if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3529 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3530 }
3531 video_mem->setVideoInfo(usage, fmt);
3532 mem = static_cast<QCameraMemory *>(video_mem);
3533 }
3534 break;
3535
3536 case CAM_STREAM_TYPE_PREVIEW:
3537 case CAM_STREAM_TYPE_POSTVIEW:
3538 case CAM_STREAM_TYPE_ANALYSIS:
3539 case CAM_STREAM_TYPE_SNAPSHOT:
3540 case CAM_STREAM_TYPE_RAW:
3541 case CAM_STREAM_TYPE_METADATA:
3542 case CAM_STREAM_TYPE_OFFLINE_PROC:
3543 case CAM_STREAM_TYPE_CALLBACK:
3544 LOGE("Stream type Not supported.for BATCH processing");
3545 break;
3546
3547 case CAM_STREAM_TYPE_DEFAULT:
3548 case CAM_STREAM_TYPE_MAX:
3549 default:
3550 break;
3551 }
3552 if (!mem) {
3553 LOGE("Failed to allocate mem");
3554 return NULL;
3555 }
3556
3557 /*Size of this buffer will be number of batch buffer */
3558 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
3559 CAM_PAD_TO_4K);
3560
3561 LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
3562
3563 if (size > 0) {
3564 // Allocating one buffer for all batch buffers
3565 rc = mem->allocate(1, size, NON_SECURE);
3566 if (rc < 0) {
3567 delete mem;
3568 return NULL;
3569 }
3570 }
3571 return mem;
3572 }
3573
3574
3575 /*===========================================================================
3576 * FUNCTION : waitForDeferredAlloc
3577 *
3578 * DESCRIPTION: Wait for deferred allocation, if applicable
3579 * (applicable only for metadata buffers so far)
3580 *
3581 * PARAMETERS :
3582 * @stream_type : type of stream to (possibly) wait for
3583 *
3584 * RETURN : None
3585 *==========================================================================*/
waitForDeferredAlloc(cam_stream_type_t stream_type)3586 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
3587 {
3588 if (stream_type == CAM_STREAM_TYPE_METADATA) {
3589 waitDeferredWork(mMetadataAllocJob);
3590 }
3591 }
3592
3593
3594 /*===========================================================================
3595 * FUNCTION : setPreviewWindow
3596 *
3597 * DESCRIPTION: set preview window impl
3598 *
3599 * PARAMETERS :
3600 * @window : ptr to window ops table struct
3601 *
3602 * RETURN : int32_t type of status
3603 * NO_ERROR -- success
3604 * none-zero failure code
3605 *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)3606 int QCamera2HardwareInterface::setPreviewWindow(
3607 struct preview_stream_ops *window)
3608 {
3609 mPreviewWindow = window;
3610 return NO_ERROR;
3611 }
3612
3613 /*===========================================================================
3614 * FUNCTION : setCallBacks
3615 *
3616 * DESCRIPTION: set callbacks impl
3617 *
3618 * PARAMETERS :
3619 * @notify_cb : notify cb
3620 * @data_cb : data cb
3621 * @data_cb_timestamp : data cb with time stamp
3622 * @get_memory : request memory ops table
3623 * @user : user data ptr
3624 *
3625 * RETURN : int32_t type of status
3626 * NO_ERROR -- success
3627 * none-zero failure code
3628 *==========================================================================*/
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)3629 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
3630 camera_data_callback data_cb,
3631 camera_data_timestamp_callback data_cb_timestamp,
3632 camera_request_memory get_memory,
3633 void *user)
3634 {
3635 mNotifyCb = notify_cb;
3636 mDataCb = data_cb;
3637 mDataCbTimestamp = data_cb_timestamp;
3638 mGetMemory = get_memory;
3639 mCallbackCookie = user;
3640 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
3641 return NO_ERROR;
3642 }
3643
3644 /*===========================================================================
3645 * FUNCTION : setJpegCallBacks
3646 *
3647 * DESCRIPTION: set JPEG callbacks impl
3648 *
3649 * PARAMETERS :
3650 * @jpegCb : Jpeg callback method
3651 * @callbackCookie : callback cookie
3652 *
3653 * RETURN : int32_t type of status
3654 * NO_ERROR -- success
3655 * none-zero failure code
3656 *==========================================================================*/
setJpegCallBacks(jpeg_data_callback jpegCb,void * callbackCookie)3657 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
3658 void *callbackCookie)
3659 {
3660 LOGH("camera id %d", getCameraId());
3661 mJpegCb = jpegCb;
3662 mJpegCallbackCookie = callbackCookie;
3663 m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
3664 }
3665
3666 /*===========================================================================
3667 * FUNCTION : enableMsgType
3668 *
3669 * DESCRIPTION: enable msg type impl
3670 *
3671 * PARAMETERS :
3672 * @msg_type : msg type mask to be enabled
3673 *
3674 * RETURN : int32_t type of status
3675 * NO_ERROR -- success
3676 * none-zero failure code
3677 *==========================================================================*/
enableMsgType(int32_t msg_type)3678 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
3679 {
3680 int32_t rc = NO_ERROR;
3681
3682 if (mParameters.isUBWCEnabled()) {
3683 /*Need Special CALLBACK stream incase application requesting for
3684 Preview callback in UBWC case*/
3685 if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3686 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3687 // Start callback channel only when preview/zsl channel is active
3688 QCameraChannel* previewCh = NULL;
3689 if (isZSLMode() && (getRecordingHintValue() != true)) {
3690 previewCh = m_channels[QCAMERA_CH_TYPE_ZSL];
3691 } else {
3692 previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3693 }
3694 QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK];
3695 if ((callbackCh != NULL) &&
3696 (previewCh != NULL) && previewCh->isActive()) {
3697 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3698 if (rc != NO_ERROR) {
3699 LOGE("START Callback Channel failed");
3700 }
3701 }
3702 }
3703 }
3704 mMsgEnabled |= msg_type;
3705 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3706 return rc;
3707 }
3708
3709 /*===========================================================================
3710 * FUNCTION : disableMsgType
3711 *
3712 * DESCRIPTION: disable msg type impl
3713 *
3714 * PARAMETERS :
3715 * @msg_type : msg type mask to be disabled
3716 *
3717 * RETURN : int32_t type of status
3718 * NO_ERROR -- success
3719 * none-zero failure code
3720 *==========================================================================*/
disableMsgType(int32_t msg_type)3721 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
3722 {
3723 int32_t rc = NO_ERROR;
3724
3725 if (mParameters.isUBWCEnabled()) {
3726 /*STOP CALLBACK STREAM*/
3727 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3728 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3729 // Stop callback channel only if it is active
3730 if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) &&
3731 (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) {
3732 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3733 if (rc != NO_ERROR) {
3734 LOGE("STOP Callback Channel failed");
3735 }
3736 }
3737 }
3738 }
3739 mMsgEnabled &= ~msg_type;
3740 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3741 return rc;
3742 }
3743
3744 /*===========================================================================
3745 * FUNCTION : msgTypeEnabled
3746 *
3747 * DESCRIPTION: impl to determine if certain msg_type is enabled
3748 *
3749 * PARAMETERS :
3750 * @msg_type : msg type mask
3751 *
3752 * RETURN : 0 -- not enabled
3753 * none 0 -- enabled
3754 *==========================================================================*/
msgTypeEnabled(int32_t msg_type)3755 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
3756 {
3757 return (mMsgEnabled & msg_type);
3758 }
3759
3760 /*===========================================================================
3761 * FUNCTION : msgTypeEnabledWithLock
3762 *
3763 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
3764 *
3765 * PARAMETERS :
3766 * @msg_type : msg type mask
3767 *
3768 * RETURN : 0 -- not enabled
3769 * none 0 -- enabled
3770 *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)3771 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
3772 {
3773 int enabled = 0;
3774 lockAPI();
3775 enabled = mMsgEnabled & msg_type;
3776 unlockAPI();
3777 return enabled;
3778 }
3779
3780 /*===========================================================================
3781 * FUNCTION : startPreview
3782 *
3783 * DESCRIPTION: start preview impl
3784 *
3785 * PARAMETERS : none
3786 *
3787 * RETURN : int32_t type of status
3788 * NO_ERROR -- success
3789 * none-zero failure code
3790 *==========================================================================*/
startPreview()3791 int QCamera2HardwareInterface::startPreview()
3792 {
3793 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW);
3794 int32_t rc = NO_ERROR;
3795
3796 LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
3797 mParameters.getRecordingHintValue());
3798
3799 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
3800
3801 updateThermalLevel((void *)&mThermalLevel);
3802
3803 setDisplayFrameSkip();
3804
3805 // start preview stream
3806 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
3807 rc = startChannel(QCAMERA_CH_TYPE_ZSL);
3808 } else {
3809 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3810 }
3811
3812 if (rc != NO_ERROR) {
3813 LOGE("failed to start channels");
3814 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3815 return rc;
3816 }
3817
3818 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
3819 && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
3820 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3821 if (rc != NO_ERROR) {
3822 LOGE("failed to start callback stream");
3823 stopChannel(QCAMERA_CH_TYPE_ZSL);
3824 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3825 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3826 return rc;
3827 }
3828 }
3829
3830 updatePostPreviewParameters();
3831 m_stateMachine.setPreviewCallbackNeeded(true);
3832
3833 // if job id is non-zero, that means the postproc init job is already
3834 // pending or complete
3835 if (mInitPProcJob == 0) {
3836 mInitPProcJob = deferPPInit();
3837 if (mInitPProcJob == 0) {
3838 LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
3839 mCameraHandle);
3840 rc = -ENOMEM;
3841 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3842 return rc;
3843 }
3844 }
3845
3846 LOGI("X rc = %d", rc);
3847 return rc;
3848 }
3849
updatePostPreviewParameters()3850 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
3851 // Enable OIS only in Camera mode and 4k2k camcoder mode
3852 int32_t rc = NO_ERROR;
3853 rc = mParameters.updateOisValue(1);
3854 return NO_ERROR;
3855 }
3856
3857 /*===========================================================================
3858 * FUNCTION : stopPreview
3859 *
3860 * DESCRIPTION: stop preview impl
3861 *
3862 * PARAMETERS : none
3863 *
3864 * RETURN : int32_t type of status
3865 * NO_ERROR -- success
3866 * none-zero failure code
3867 *==========================================================================*/
stopPreview()3868 int QCamera2HardwareInterface::stopPreview()
3869 {
3870 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOPPREVIEW);
3871 LOGI("E");
3872 mNumPreviewFaces = -1;
3873 mActiveAF = false;
3874
3875 // Disable power Hint for preview
3876 m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
3877
3878 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
3879
3880 // stop preview stream
3881 stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3882 stopChannel(QCAMERA_CH_TYPE_ZSL);
3883 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3884 stopChannel(QCAMERA_CH_TYPE_RAW);
3885
3886 m_cbNotifier.flushPreviewNotifications();
3887 //add for ts makeup
3888 #ifdef TARGET_TS_MAKEUP
3889 ts_makeup_finish();
3890 #endif
3891 // delete all channels from preparePreview
3892 unpreparePreview();
3893
3894 m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_PREVIEW);
3895 LOGI("X");
3896 return NO_ERROR;
3897 }
3898
3899 /*===========================================================================
3900 * FUNCTION : storeMetaDataInBuffers
3901 *
3902 * DESCRIPTION: enable store meta data in buffers for video frames impl
3903 *
3904 * PARAMETERS :
3905 * @enable : flag if need enable
3906 *
3907 * RETURN : int32_t type of status
3908 * NO_ERROR -- success
3909 * none-zero failure code
3910 *==========================================================================*/
storeMetaDataInBuffers(int enable)3911 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
3912 {
3913 mStoreMetaDataInFrame = enable;
3914 return NO_ERROR;
3915 }
3916
3917 /*===========================================================================
3918 * FUNCTION : preStartRecording
3919 *
3920 * DESCRIPTION: Prepare start recording impl
3921 *
3922 * PARAMETERS : none
3923 *
3924 * RETURN : int32_t type of status
3925 * NO_ERROR -- success
3926 * none-zero failure code
3927 *==========================================================================*/
preStartRecording()3928 int QCamera2HardwareInterface::preStartRecording()
3929 {
3930 int32_t rc = NO_ERROR;
3931 LOGH("E");
3932 if (mParameters.getRecordingHintValue() == false) {
3933
3934 // Give HWI control to restart preview only in single camera mode.
3935 // In dual-cam mode, this control belongs to muxer.
3936 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
3937 LOGH("start recording when hint is false, stop preview first");
3938 stopPreview();
3939
3940 // Set recording hint to TRUE
3941 mParameters.updateRecordingHintValue(TRUE);
3942 rc = preparePreview();
3943 if (rc == NO_ERROR) {
3944 rc = startPreview();
3945 }
3946 }
3947 else
3948 {
3949 // For dual cam mode, update the flag mPreviewRestartNeeded to true
3950 // Restart control will be handled by muxer.
3951 mPreviewRestartNeeded = true;
3952 }
3953 }
3954
3955 LOGH("X rc = %d", rc);
3956 return rc;
3957 }
3958
3959 /*===========================================================================
3960 * FUNCTION : startRecording
3961 *
3962 * DESCRIPTION: start recording impl
3963 *
3964 * PARAMETERS : none
3965 *
3966 * RETURN : int32_t type of status
3967 * NO_ERROR -- success
3968 * none-zero failure code
3969 *==========================================================================*/
startRecording()3970 int QCamera2HardwareInterface::startRecording()
3971 {
3972 int32_t rc = NO_ERROR;
3973
3974 LOGI("E");
3975
3976 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
3977
3978 //link meta stream with video channel if low power mode.
3979 if (isLowPowerMode()) {
3980 // Find and try to link a metadata stream from preview channel
3981 QCameraChannel *pMetaChannel = NULL;
3982 QCameraStream *pMetaStream = NULL;
3983 QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
3984
3985 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
3986 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3987 uint32_t streamNum = pMetaChannel->getNumOfStreams();
3988 QCameraStream *pStream = NULL;
3989 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
3990 pStream = pMetaChannel->getStreamByIndex(i);
3991 if ((NULL != pStream) &&
3992 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
3993 pMetaStream = pStream;
3994 break;
3995 }
3996 }
3997 }
3998
3999 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4000 rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
4001 if (NO_ERROR != rc) {
4002 LOGW("Metadata stream link failed %d", rc);
4003 }
4004 }
4005 }
4006
4007 if (rc == NO_ERROR) {
4008 rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
4009 }
4010
4011 if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
4012 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
4013 if (!mParameters.is4k2kVideoResolution()) {
4014 // Find and try to link a metadata stream from preview channel
4015 QCameraChannel *pMetaChannel = NULL;
4016 QCameraStream *pMetaStream = NULL;
4017
4018 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4019 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
4020 uint32_t streamNum = pMetaChannel->getNumOfStreams();
4021 QCameraStream *pStream = NULL;
4022 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
4023 pStream = pMetaChannel->getStreamByIndex(i);
4024 if ((NULL != pStream) &&
4025 (CAM_STREAM_TYPE_METADATA ==
4026 pStream->getMyType())) {
4027 pMetaStream = pStream;
4028 break;
4029 }
4030 }
4031 }
4032
4033 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4034 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
4035 if (NO_ERROR != rc) {
4036 LOGW("Metadata stream link failed %d", rc);
4037 }
4038 }
4039 }
4040 LOGH("START snapshot Channel for TNR processing");
4041 rc = pChannel->start();
4042 }
4043
4044 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
4045
4046 if (rc == NO_ERROR) {
4047 // Set power Hint for video encoding
4048 m_perfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0);
4049 }
4050
4051 LOGI("X rc = %d", rc);
4052 return rc;
4053 }
4054
4055 /*===========================================================================
4056 * FUNCTION : stopRecording
4057 *
4058 * DESCRIPTION: stop recording impl
4059 *
4060 * PARAMETERS : none
4061 *
4062 * RETURN : int32_t type of status
4063 * NO_ERROR -- success
4064 * none-zero failure code
4065 *==========================================================================*/
stopRecording()4066 int QCamera2HardwareInterface::stopRecording()
4067 {
4068 LOGI("E");
4069
4070 // Disable power hint for video encoding
4071 m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE);
4072
4073 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
4074
4075 // stop snapshot channel
4076 if (mParameters.isTNRSnapshotEnabled()) {
4077 LOGH("STOP snapshot Channel for TNR processing");
4078 stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4079 }
4080 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
4081
4082 m_cbNotifier.flushVideoNotifications();
4083
4084 m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_RECORDING);
4085
4086 LOGI("X rc = %d", rc);
4087 return rc;
4088 }
4089
4090 /*===========================================================================
4091 * FUNCTION : releaseRecordingFrame
4092 *
4093 * DESCRIPTION: return video frame impl
4094 *
4095 * PARAMETERS :
4096 * @opaque : ptr to video frame to be returned
4097 *
4098 * RETURN : int32_t type of status
4099 * NO_ERROR -- success
4100 * none-zero failure code
4101 *==========================================================================*/
releaseRecordingFrame(const void * opaque)4102 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
4103 {
4104 int32_t rc = UNKNOWN_ERROR;
4105 QCameraVideoChannel *pChannel =
4106 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
4107 LOGD("opaque data = %p",opaque);
4108
4109 if(pChannel != NULL) {
4110 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
4111 }
4112 return rc;
4113 }
4114
4115 /*===========================================================================
4116 * FUNCTION : autoFocus
4117 *
4118 * DESCRIPTION: start auto focus impl
4119 *
4120 * PARAMETERS : none
4121 *
4122 * RETURN : int32_t type of status
4123 * NO_ERROR -- success
4124 * none-zero failure code
4125 *==========================================================================*/
autoFocus()4126 int QCamera2HardwareInterface::autoFocus()
4127 {
4128 int rc = NO_ERROR;
4129 cam_focus_mode_type focusMode = mParameters.getFocusMode();
4130 LOGH("E");
4131
4132 switch (focusMode) {
4133 case CAM_FOCUS_MODE_AUTO:
4134 case CAM_FOCUS_MODE_MACRO:
4135 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4136 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4137 mActiveAF = true;
4138 LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
4139 focusMode, m_currentFocusState);
4140 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
4141 break;
4142 case CAM_FOCUS_MODE_INFINITY:
4143 case CAM_FOCUS_MODE_FIXED:
4144 case CAM_FOCUS_MODE_EDOF:
4145 default:
4146 LOGI("No ops in focusMode (%d)", focusMode);
4147 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
4148 break;
4149 }
4150
4151 if (NO_ERROR != rc) {
4152 mActiveAF = false;
4153 }
4154 LOGH("X rc = %d", rc);
4155 return rc;
4156 }
4157
4158 /*===========================================================================
4159 * FUNCTION : cancelAutoFocus
4160 *
4161 * DESCRIPTION: cancel auto focus impl
4162 *
4163 * PARAMETERS : none
4164 *
4165 * RETURN : int32_t type of status
4166 * NO_ERROR -- success
4167 * none-zero failure code
4168 *==========================================================================*/
cancelAutoFocus()4169 int QCamera2HardwareInterface::cancelAutoFocus()
4170 {
4171 int rc = NO_ERROR;
4172 cam_focus_mode_type focusMode = mParameters.getFocusMode();
4173
4174 switch (focusMode) {
4175 case CAM_FOCUS_MODE_AUTO:
4176 case CAM_FOCUS_MODE_MACRO:
4177 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4178 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4179 mActiveAF = false;
4180 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
4181 break;
4182 case CAM_FOCUS_MODE_INFINITY:
4183 case CAM_FOCUS_MODE_FIXED:
4184 case CAM_FOCUS_MODE_EDOF:
4185 default:
4186 LOGD("No ops in focusMode (%d)", focusMode);
4187 break;
4188 }
4189 return rc;
4190 }
4191
4192 /*===========================================================================
4193 * FUNCTION : processUFDumps
4194 *
4195 * DESCRIPTION: process UF jpeg dumps for refocus support
4196 *
4197 * PARAMETERS :
4198 * @evt : payload of jpeg event, including information about jpeg encoding
4199 * status, jpeg size and so on.
4200 *
4201 * RETURN : int32_t type of status
4202 * NO_ERROR -- success
4203 * none-zero failure code
4204 *
4205 * NOTE : none
4206 *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)4207 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
4208 {
4209 bool ret = true;
4210 if (mParameters.isUbiRefocus()) {
4211 int index = (int)getOutputImageCount();
4212 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
4213 char name[FILENAME_MAX];
4214
4215 camera_memory_t *jpeg_mem = NULL;
4216 omx_jpeg_ouput_buf_t *jpeg_out = NULL;
4217 size_t dataLen;
4218 uint8_t *dataPtr;
4219 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
4220 LOGE("Init PProc Deferred work failed");
4221 return false;
4222 }
4223 if (!m_postprocessor.getJpegMemOpt()) {
4224 dataLen = evt->out_data.buf_filled_len;
4225 dataPtr = evt->out_data.buf_vaddr;
4226 } else {
4227 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
4228 if (!jpeg_out) {
4229 LOGE("Null pointer detected");
4230 return false;
4231 }
4232 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
4233 if (!jpeg_mem) {
4234 LOGE("Null pointer detected");
4235 return false;
4236 }
4237 dataPtr = (uint8_t *)jpeg_mem->data;
4238 dataLen = jpeg_mem->size;
4239 }
4240
4241 if (allFocusImage) {
4242 snprintf(name, sizeof(name), "AllFocusImage");
4243 index = -1;
4244 } else {
4245 snprintf(name, sizeof(name), "%d", 0);
4246 }
4247 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
4248 dataPtr, dataLen);
4249 LOGD("Dump the image %d %d allFocusImage %d",
4250 getOutputImageCount(), index, allFocusImage);
4251 setOutputImageCount(getOutputImageCount() + 1);
4252 if (!allFocusImage) {
4253 ret = false;
4254 }
4255 }
4256 return ret;
4257 }
4258
4259 /*===========================================================================
4260 * FUNCTION : unconfigureAdvancedCapture
4261 *
4262 * DESCRIPTION: unconfigure Advanced Capture.
4263 *
4264 * PARAMETERS : none
4265 *
4266 * RETURN : int32_t type of status
4267 * NO_ERROR -- success
4268 * none-zero failure code
4269 *==========================================================================*/
unconfigureAdvancedCapture()4270 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
4271 {
4272 int32_t rc = NO_ERROR;
4273
4274 /*Disable Quadra CFA mode*/
4275 LOGH("Disabling Quadra CFA mode");
4276 mParameters.setQuadraCfaMode(false, true);
4277
4278 if (mAdvancedCaptureConfigured) {
4279
4280 mAdvancedCaptureConfigured = false;
4281
4282 if(mIs3ALocked) {
4283 mParameters.set3ALock(false);
4284 mIs3ALocked = false;
4285 }
4286 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
4287 rc = mParameters.setToneMapMode(true, true);
4288 if (rc != NO_ERROR) {
4289 LOGW("Failed to enable tone map during HDR/AEBracketing");
4290 }
4291 mHDRBracketingEnabled = false;
4292 rc = mParameters.stopAEBracket();
4293 } else if ((mParameters.isChromaFlashEnabled())
4294 || (mFlashConfigured && !mLongshotEnabled)
4295 || (mLowLightConfigured == true)
4296 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4297 rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured);
4298 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4299 rc = configureAFBracketing(false);
4300 } else if (mParameters.isOptiZoomEnabled()) {
4301 rc = mParameters.setAndCommitZoom(mZoomLevel);
4302 setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
4303 } else if (mParameters.isStillMoreEnabled()) {
4304 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
4305 stillmore_config.burst_count = 0;
4306 mParameters.setStillMoreSettings(stillmore_config);
4307
4308 /* If SeeMore is running, it will handle re-enabling tone map */
4309 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4310 rc = mParameters.setToneMapMode(true, true);
4311 if (rc != NO_ERROR) {
4312 LOGW("Failed to enable tone map during StillMore");
4313 }
4314 }
4315
4316 /* Re-enable Tintless */
4317 mParameters.setTintless(true);
4318 } else {
4319 LOGW("No Advanced Capture feature enabled!!");
4320 rc = BAD_VALUE;
4321 }
4322 }
4323
4324 return rc;
4325 }
4326
4327 /*===========================================================================
4328 * FUNCTION : configureAdvancedCapture
4329 *
4330 * DESCRIPTION: configure Advanced Capture.
4331 *
4332 * PARAMETERS : none
4333 *
4334 * RETURN : int32_t type of status
4335 * NO_ERROR -- success
4336 * none-zero failure code
4337 *==========================================================================*/
configureAdvancedCapture()4338 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
4339 {
4340 LOGH("E");
4341 int32_t rc = NO_ERROR;
4342
4343 rc = mParameters.checkFeatureConcurrency();
4344 if (rc != NO_ERROR) {
4345 LOGE("Cannot support Advanced capture modes");
4346 return rc;
4347 }
4348 /*Enable Quadra CFA mode*/
4349 LOGH("Enabling Quadra CFA mode");
4350 mParameters.setQuadraCfaMode(true, true);
4351
4352 setOutputImageCount(0);
4353 mInputCount = 0;
4354 mAdvancedCaptureConfigured = true;
4355 /* Display should be disabled for advanced modes */
4356 bool bSkipDisplay = true;
4357
4358 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
4359 // no Advance capture settings for Aux camera
4360 LOGH("X Secondary Camera, no need to process!! ");
4361 return rc;
4362 }
4363
4364 /* Do not stop display if in stillmore livesnapshot */
4365 if (mParameters.isStillMoreEnabled() &&
4366 mParameters.isSeeMoreEnabled()) {
4367 bSkipDisplay = false;
4368 }
4369 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4370 rc = configureAFBracketing();
4371 } else if (mParameters.isOptiZoomEnabled()) {
4372 rc = configureOptiZoom();
4373 } else if(mParameters.isHDREnabled()) {
4374 rc = configureHDRBracketing();
4375 if (mHDRBracketingEnabled) {
4376 rc = mParameters.setToneMapMode(false, true);
4377 if (rc != NO_ERROR) {
4378 LOGW("Failed to disable tone map during HDR");
4379 }
4380 }
4381 } else if (mParameters.isAEBracketEnabled()) {
4382 rc = mParameters.setToneMapMode(false, true);
4383 if (rc != NO_ERROR) {
4384 LOGW("Failed to disable tone map during AEBracketing");
4385 }
4386 rc = configureAEBracketing();
4387 } else if (mParameters.isStillMoreEnabled()) {
4388 bSkipDisplay = false;
4389 rc = configureStillMore();
4390 } else if ((mParameters.isChromaFlashEnabled())
4391 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4392 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4393 rc = mParameters.configFrameCapture(TRUE);
4394 if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) {
4395 mLowLightConfigured = true;
4396 }
4397 } else if (mFlashNeeded && !mLongshotEnabled) {
4398 rc = mParameters.configFrameCapture(TRUE);
4399 mFlashConfigured = true;
4400 bSkipDisplay = false;
4401 } else {
4402 LOGH("Advanced Capture feature not enabled!! ");
4403 mAdvancedCaptureConfigured = false;
4404 bSkipDisplay = false;
4405 }
4406
4407 LOGH("Stop preview temporarily for advanced captures");
4408 setDisplaySkip(bSkipDisplay);
4409
4410 LOGH("X rc = %d", rc);
4411 return rc;
4412 }
4413
4414 /*===========================================================================
4415 * FUNCTION : configureAFBracketing
4416 *
4417 * DESCRIPTION: configure AF Bracketing.
4418 *
4419 * PARAMETERS : none
4420 *
4421 * RETURN : int32_t type of status
4422 * NO_ERROR -- success
4423 * none-zero failure code
4424 *==========================================================================*/
configureAFBracketing(bool enable)4425 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
4426 {
4427 LOGH("E");
4428 int32_t rc = NO_ERROR;
4429 cam_af_bracketing_t *af_bracketing_need;
4430
4431 if (mParameters.isUbiRefocus()) {
4432 af_bracketing_need =
4433 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
4434 } else {
4435 af_bracketing_need =
4436 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
4437 }
4438
4439 //Enable AF Bracketing.
4440 cam_af_bracketing_t afBracket;
4441 memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
4442 afBracket.enable = enable;
4443 afBracket.burst_count = af_bracketing_need->burst_count;
4444
4445 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
4446 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
4447 LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
4448 }
4449 //Send cmd to backend to set AF Bracketing for Ubi Focus.
4450 rc = mParameters.commitAFBracket(afBracket);
4451 if ( NO_ERROR != rc ) {
4452 LOGE("cannot configure AF bracketing");
4453 return rc;
4454 }
4455 if (enable) {
4456 mParameters.set3ALock(true);
4457 mIs3ALocked = true;
4458 }
4459 LOGH("X rc = %d", rc);
4460 return rc;
4461 }
4462
4463 /*===========================================================================
4464 * FUNCTION : configureHDRBracketing
4465 *
4466 * DESCRIPTION: configure HDR Bracketing.
4467 *
4468 * PARAMETERS : none
4469 *
4470 * RETURN : int32_t type of status
4471 * NO_ERROR -- success
4472 * none-zero failure code
4473 *==========================================================================*/
configureHDRBracketing()4474 int32_t QCamera2HardwareInterface::configureHDRBracketing()
4475 {
4476 LOGH("E");
4477 int32_t rc = NO_ERROR;
4478
4479 cam_hdr_bracketing_info_t& hdrBracketingSetting =
4480 gCamCapability[mCameraId]->hdr_bracketing_setting;
4481
4482 // 'values' should be in "idx1,idx2,idx3,..." format
4483 uint32_t hdrFrameCount =
4484 hdrBracketingSetting.num_frames;
4485 LOGH("HDR values %d, %d frame count: %u",
4486 (int8_t) hdrBracketingSetting.exp_val.values[0],
4487 (int8_t) hdrBracketingSetting.exp_val.values[1],
4488 hdrFrameCount);
4489
4490 // Enable AE Bracketing for HDR
4491 cam_exp_bracketing_t aeBracket;
4492 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
4493 aeBracket.mode =
4494 hdrBracketingSetting.exp_val.mode;
4495
4496 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
4497 mHDRBracketingEnabled = true;
4498 }
4499
4500 String8 tmp;
4501 for (uint32_t i = 0; i < hdrFrameCount; i++) {
4502 tmp.appendFormat("%d",
4503 (int8_t) hdrBracketingSetting.exp_val.values[i]);
4504 tmp.append(",");
4505 }
4506 if (mParameters.isHDR1xFrameEnabled()
4507 && mParameters.isHDR1xExtraBufferNeeded()) {
4508 tmp.appendFormat("%d", 0);
4509 tmp.append(",");
4510 }
4511
4512 if( !tmp.isEmpty() &&
4513 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
4514 //Trim last comma
4515 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
4516 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
4517 }
4518
4519 LOGH("HDR config values %s",
4520 aeBracket.values);
4521 rc = mParameters.setHDRAEBracket(aeBracket);
4522 if ( NO_ERROR != rc ) {
4523 LOGE("cannot configure HDR bracketing");
4524 return rc;
4525 }
4526 LOGH("X rc = %d", rc);
4527 return rc;
4528 }
4529
4530 /*===========================================================================
4531 * FUNCTION : configureAEBracketing
4532 *
4533 * DESCRIPTION: configure AE Bracketing.
4534 *
4535 * PARAMETERS : none
4536 *
4537 * RETURN : int32_t type of status
4538 * NO_ERROR -- success
4539 * none-zero failure code
4540 *==========================================================================*/
configureAEBracketing()4541 int32_t QCamera2HardwareInterface::configureAEBracketing()
4542 {
4543 LOGH("E");
4544 int32_t rc = NO_ERROR;
4545
4546 rc = mParameters.setAEBracketing();
4547 if ( NO_ERROR != rc ) {
4548 LOGE("cannot configure AE bracketing");
4549 return rc;
4550 }
4551 LOGH("X rc = %d", rc);
4552 return rc;
4553 }
4554
4555 /*===========================================================================
4556 * FUNCTION : configureOptiZoom
4557 *
4558 * DESCRIPTION: configure Opti Zoom.
4559 *
4560 * PARAMETERS : none
4561 *
4562 * RETURN : int32_t type of status
4563 * NO_ERROR -- success
4564 * none-zero failure code
4565 *==========================================================================*/
configureOptiZoom()4566 int32_t QCamera2HardwareInterface::configureOptiZoom()
4567 {
4568 int32_t rc = NO_ERROR;
4569
4570 //store current zoom level.
4571 mZoomLevel = mParameters.getParmZoomLevel();
4572
4573 //set zoom level to 1x;
4574 mParameters.setAndCommitZoom(0);
4575
4576 mParameters.set3ALock(true);
4577 mIs3ALocked = true;
4578
4579 return rc;
4580 }
4581
4582 /*===========================================================================
4583 * FUNCTION : configureStillMore
4584 *
4585 * DESCRIPTION: configure StillMore.
4586 *
4587 * PARAMETERS : none
4588 *
4589 * RETURN : int32_t type of status
4590 * NO_ERROR -- success
4591 * none-zero failure code
4592 *==========================================================================*/
configureStillMore()4593 int32_t QCamera2HardwareInterface::configureStillMore()
4594 {
4595 int32_t rc = NO_ERROR;
4596 uint8_t burst_cnt = 0;
4597 cam_still_more_t stillmore_config;
4598 cam_still_more_t stillmore_cap;
4599
4600 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
4601 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4602 rc = mParameters.setToneMapMode(false, true);
4603 if (rc != NO_ERROR) {
4604 LOGW("Failed to disable tone map during StillMore");
4605 }
4606 }
4607
4608 /* Lock 3A */
4609 mParameters.set3ALock(true);
4610 mIs3ALocked = true;
4611
4612 /* Disable Tintless */
4613 mParameters.setTintless(false);
4614
4615 /* Initialize burst count from capability */
4616 stillmore_cap = mParameters.getStillMoreCapability();
4617 burst_cnt = stillmore_cap.max_burst_count;
4618
4619 /* Reconfigure burst count from dynamic scene data */
4620 cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
4621 if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
4622 dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
4623 burst_cnt = dynamic_img_data.input_count;
4624 }
4625
4626 /* Reconfigure burst count in the case of liveshot */
4627 if (mParameters.isSeeMoreEnabled()) {
4628 burst_cnt = 1;
4629 }
4630
4631 /* Reconfigure burst count from user input */
4632 char prop[PROPERTY_VALUE_MAX];
4633 property_get("persist.camera.imglib.stillmore", prop, "0");
4634 uint8_t burst_setprop = (uint32_t)atoi(prop);
4635 if (burst_setprop != 0) {
4636 if ((burst_setprop < stillmore_cap.min_burst_count) ||
4637 (burst_setprop > stillmore_cap.max_burst_count)) {
4638 burst_cnt = stillmore_cap.max_burst_count;
4639 } else {
4640 burst_cnt = burst_setprop;
4641 }
4642 }
4643
4644 memset(&stillmore_config, 0, sizeof(cam_still_more_t));
4645 stillmore_config.burst_count = burst_cnt;
4646 mParameters.setStillMoreSettings(stillmore_config);
4647
4648 LOGH("Stillmore burst %d", burst_cnt);
4649
4650 return rc;
4651 }
4652
4653 /*===========================================================================
4654 * FUNCTION : stopAdvancedCapture
4655 *
4656 * DESCRIPTION: stops advanced capture based on capture type
4657 *
4658 * PARAMETERS :
4659 * @pChannel : channel.
4660 *
4661 * RETURN : int32_t type of status
4662 * NO_ERROR -- success
4663 * none-zero failure code
4664 *==========================================================================*/
stopAdvancedCapture(QCameraPicChannel * pChannel)4665 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
4666 QCameraPicChannel *pChannel)
4667 {
4668 LOGH("stop bracketig");
4669 int32_t rc = NO_ERROR;
4670
4671 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4672 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4673 } else if (mParameters.isChromaFlashEnabled()
4674 || (mFlashConfigured && !mLongshotEnabled)
4675 || (mLowLightConfigured == true)
4676 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4677 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
4678 mFlashConfigured = false;
4679 mLowLightConfigured = false;
4680 } else if(mParameters.isHDREnabled()
4681 || mParameters.isAEBracketEnabled()) {
4682 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4683 } else if (mParameters.isOptiZoomEnabled()) {
4684 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
4685 } else if (mParameters.isStillMoreEnabled()) {
4686 LOGH("stopAdvancedCapture not needed for StillMore");
4687 } else {
4688 LOGH("No Advanced Capture feature enabled!");
4689 rc = BAD_VALUE;
4690 }
4691 return rc;
4692 }
4693
4694 /*===========================================================================
4695 * FUNCTION : startAdvancedCapture
4696 *
4697 * DESCRIPTION: starts advanced capture based on capture type
4698 *
4699 * PARAMETERS :
4700 * @pChannel : channel.
4701 *
4702 * RETURN : int32_t type of status
4703 * NO_ERROR -- success
4704 * none-zero failure code
4705 *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)4706 int32_t QCamera2HardwareInterface::startAdvancedCapture(
4707 QCameraPicChannel *pChannel)
4708 {
4709 LOGH("Start bracketing");
4710 int32_t rc = NO_ERROR;
4711
4712 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4713 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4714 } else if (mParameters.isOptiZoomEnabled()) {
4715 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
4716 } else if (mParameters.isStillMoreEnabled()) {
4717 LOGH("startAdvancedCapture not needed for StillMore");
4718 } else if (mParameters.isHDREnabled()
4719 || mParameters.isAEBracketEnabled()) {
4720 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4721 } else if (mParameters.isChromaFlashEnabled()
4722 || (mFlashNeeded && !mLongshotEnabled)
4723 || (mLowLightConfigured == true)
4724 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4725 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
4726 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
4727 } else {
4728 LOGE("No Advanced Capture feature enabled!");
4729 rc = BAD_VALUE;
4730 }
4731 return rc;
4732 }
4733
4734 /*===========================================================================
4735 * FUNCTION : preTakePicture
4736 *
4737 * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
4738 *
4739 * PARAMETERS : none
4740 *
4741 * RETURN : int32_t type of status
4742 * NO_ERROR -- success
4743 * none-zero failure code
4744 *==========================================================================*/
preTakePicture()4745 int QCamera2HardwareInterface::preTakePicture()
4746 {
4747 int32_t rc = NO_ERROR;
4748 LOGH("E");
4749 if (mParameters.getRecordingHintValue() == true) {
4750
4751 // Give HWI control to restart preview only in single camera mode.
4752 // In dual-cam mode, this control belongs to muxer.
4753 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4754 LOGH("restart preview if rec hint is true and preview is running");
4755 stopPreview();
4756 mParameters.updateRecordingHintValue(FALSE);
4757 // start preview again
4758 rc = preparePreview();
4759 if (rc == NO_ERROR) {
4760 rc = startPreview();
4761 if (rc != NO_ERROR) {
4762 unpreparePreview();
4763 }
4764 }
4765 }
4766 else
4767 {
4768 // For dual cam mode, update the flag mPreviewRestartNeeded to true
4769 // Restart control will be handled by muxer.
4770 mPreviewRestartNeeded = true;
4771 }
4772 }
4773
4774 LOGH("X rc = %d", rc);
4775 return rc;
4776 }
4777
4778 /*===========================================================================
4779 * FUNCTION : takePicture
4780 *
4781 * DESCRIPTION: take picture impl
4782 *
4783 * PARAMETERS : none
4784 *
4785 * RETURN : int32_t type of status
4786 * NO_ERROR -- success
4787 * none-zero failure code
4788 *==========================================================================*/
takePicture()4789 int QCamera2HardwareInterface::takePicture()
4790 {
4791 int rc = NO_ERROR;
4792
4793 // Get total number for snapshots (retro + regular)
4794 uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4795 // Get number of retro-active snapshots
4796 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
4797 LOGH("E");
4798
4799 //Set rotation value from user settings as Jpeg rotation
4800 //to configure back-end modules.
4801 mParameters.setJpegRotation(mParameters.getRotation());
4802
4803 // Check if retro-active snapshots are not enabled
4804 if (!isRetroPicture() || !mParameters.isZSLMode()) {
4805 numRetroSnapshots = 0;
4806 LOGH("Reset retro snaphot count to zero");
4807 }
4808
4809 //Do special configure for advanced capture modes.
4810 rc = configureAdvancedCapture();
4811 if (rc != NO_ERROR) {
4812 LOGE("Unsupported capture call");
4813 return rc;
4814 }
4815
4816 if(mActiveCamera == MM_CAMERA_DUAL_CAM) {
4817 /*Need to remove once we have dual camera fusion*/
4818 numSnapshots = numSnapshots/MM_CAMERA_MAX_CAM_CNT;
4819 }
4820
4821 if (mAdvancedCaptureConfigured) {
4822 numSnapshots = mParameters.getBurstCountForAdvancedCapture();
4823 }
4824 LOGI("snap count = %d zsl = %d advanced = %d",
4825 numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured);
4826
4827 if (mParameters.isZSLMode()) {
4828 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
4829 QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
4830 if (NULL != pPicChannel) {
4831
4832 if (mParameters.getofflineRAW()) {
4833 startRAWChannel(pPicChannel);
4834 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4835 if (pPicChannel == NULL) {
4836 LOGE("RAW Channel is NULL in Manual capture mode");
4837 stopRAWChannel();
4838 return UNKNOWN_ERROR;
4839 }
4840 }
4841
4842 rc = configureOnlineRotation(*pPicChannel);
4843 if (rc != NO_ERROR) {
4844 LOGE("online rotation failed");
4845 return rc;
4846 }
4847
4848 // start postprocessor
4849 DeferWorkArgs args;
4850 memset(&args, 0, sizeof(DeferWorkArgs));
4851
4852 args.pprocArgs = pPicChannel;
4853
4854 // No need to wait for mInitPProcJob here, because it was
4855 // queued in startPreview, and will definitely be processed before
4856 // mReprocJob can begin.
4857 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4858 args);
4859 if (mReprocJob == 0) {
4860 LOGE("Failure: Unable to start pproc");
4861 return -ENOMEM;
4862 }
4863
4864 // Check if all preview buffers are mapped before creating
4865 // a jpeg session as preview stream buffers are queried during the same
4866 uint8_t numStreams = pChannel->getNumOfStreams();
4867 QCameraStream *pStream = NULL;
4868 QCameraStream *pPreviewStream = NULL;
4869 for (uint8_t i = 0 ; i < numStreams ; i++ ) {
4870 pStream = pChannel->getStreamByIndex(i);
4871 if (!pStream)
4872 continue;
4873 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
4874 pPreviewStream = pStream;
4875 break;
4876 }
4877 }
4878 if (pPreviewStream != NULL) {
4879 Mutex::Autolock l(mMapLock);
4880 QCameraMemory *pMemory = pStream->getStreamBufs();
4881 if (!pMemory) {
4882 LOGE("Error!! pMemory is NULL");
4883 return -ENOMEM;
4884 }
4885
4886 uint8_t waitCnt = 2;
4887 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
4888 LOGL(" Waiting for preview buffers to be mapped");
4889 mMapCond.waitRelative(
4890 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
4891 LOGL("Wait completed!!");
4892 waitCnt--;
4893 }
4894 // If all buffers are not mapped after retries, assert
4895 assert(pMemory->checkIfAllBuffersMapped());
4896 } else {
4897 assert(pPreviewStream);
4898 }
4899
4900 // Create JPEG session
4901 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
4902 args);
4903 if (mJpegJob == 0) {
4904 LOGE("Failed to queue CREATE_JPEG_SESSION");
4905 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4906 LOGE("Reprocess Deferred work was failed");
4907 }
4908 m_postprocessor.stop();
4909 return -ENOMEM;
4910 }
4911
4912 if (mAdvancedCaptureConfigured) {
4913 rc = startAdvancedCapture(pPicChannel);
4914 if (rc != NO_ERROR) {
4915 LOGE("cannot start zsl advanced capture");
4916 return rc;
4917 }
4918 }
4919 if (mLongshotEnabled && mPrepSnapRun) {
4920 mCameraHandle->ops->start_zsl_snapshot(
4921 mCameraHandle->camera_handle,
4922 pPicChannel->getMyHandle());
4923 }
4924 // If frame sync is ON and it is a SECONDARY camera,
4925 // we do not need to send the take picture command to interface
4926 // It will be handled along with PRIMARY camera takePicture request
4927 mm_camera_req_buf_t buf;
4928 memset(&buf, 0x0, sizeof(buf));
4929 if ((!mParameters.isAdvCamFeaturesEnabled() &&
4930 !mFlashNeeded &&
4931 !isLongshotEnabled() &&
4932 isFrameSyncEnabled()) &&
4933 (getRelatedCamSyncInfo()->sync_control ==
4934 CAM_SYNC_RELATED_SENSORS_ON)) {
4935 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
4936 buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
4937 buf.num_buf_requested = numSnapshots;
4938 rc = pPicChannel->takePicture(&buf);
4939 if (rc != NO_ERROR) {
4940 LOGE("FS_DBG cannot take ZSL picture, stop pproc");
4941 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4942 LOGE("Reprocess Deferred work failed");
4943 return UNKNOWN_ERROR;
4944 }
4945 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4946 LOGE("Jpeg Deferred work failed");
4947 return UNKNOWN_ERROR;
4948 }
4949 m_postprocessor.stop();
4950 return rc;
4951 }
4952 LOGI("PRIMARY camera: send frame sync takePicture!!");
4953 }
4954 } else {
4955 buf.type = MM_CAMERA_REQ_SUPER_BUF;
4956 buf.num_buf_requested = numSnapshots;
4957 buf.num_retro_buf_requested = numRetroSnapshots;
4958 rc = pPicChannel->takePicture(&buf);
4959 if (rc != NO_ERROR) {
4960 LOGE("cannot take ZSL picture, stop pproc");
4961 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4962 LOGE("Reprocess Deferred work failed");
4963 return UNKNOWN_ERROR;
4964 }
4965 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4966 LOGE("Jpeg Deferred work failed");
4967 return UNKNOWN_ERROR;
4968 }
4969 m_postprocessor.stop();
4970 return rc;
4971 }
4972 }
4973 } else {
4974 LOGE("ZSL channel is NULL");
4975 return UNKNOWN_ERROR;
4976 }
4977 } else {
4978
4979 // start snapshot
4980 if (mParameters.isJpegPictureFormat() ||
4981 mParameters.isNV16PictureFormat() ||
4982 mParameters.isNV21PictureFormat()) {
4983
4984 //STOP Preview for Non ZSL use case
4985 stopPreview();
4986
4987 //Config CAPTURE channels
4988 rc = declareSnapshotStreams();
4989 if (NO_ERROR != rc) {
4990 return rc;
4991 }
4992
4993 rc = addCaptureChannel();
4994 if ((rc == NO_ERROR) &&
4995 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
4996
4997 if (!mParameters.getofflineRAW()) {
4998 rc = configureOnlineRotation(
4999 *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
5000 if (rc != NO_ERROR) {
5001 LOGE("online rotation failed");
5002 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5003 return rc;
5004 }
5005 }
5006
5007 DeferWorkArgs args;
5008 memset(&args, 0, sizeof(DeferWorkArgs));
5009
5010 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
5011
5012 // No need to wait for mInitPProcJob here, because it was
5013 // queued in startPreview, and will definitely be processed before
5014 // mReprocJob can begin.
5015 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5016 args);
5017 if (mReprocJob == 0) {
5018 LOGE("Failure: Unable to start pproc");
5019 return -ENOMEM;
5020 }
5021
5022 // Create JPEG session
5023 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5024 args);
5025 if (mJpegJob == 0) {
5026 LOGE("Failed to queue CREATE_JPEG_SESSION");
5027 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5028 LOGE("Reprocess Deferred work was failed");
5029 }
5030 m_postprocessor.stop();
5031 return -ENOMEM;
5032 }
5033
5034 // start catpure channel
5035 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
5036 if (rc != NO_ERROR) {
5037 LOGE("cannot start capture channel");
5038 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5039 LOGE("Reprocess Deferred work failed");
5040 return UNKNOWN_ERROR;
5041 }
5042 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5043 LOGE("Jpeg Deferred work failed");
5044 return UNKNOWN_ERROR;
5045 }
5046 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5047 return rc;
5048 }
5049
5050 QCameraPicChannel *pCapChannel =
5051 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5052 if (NULL != pCapChannel) {
5053 if (mParameters.isUbiFocusEnabled() ||
5054 mParameters.isUbiRefocus() ||
5055 mParameters.isChromaFlashEnabled()) {
5056 rc = startAdvancedCapture(pCapChannel);
5057 if (rc != NO_ERROR) {
5058 LOGE("cannot start advanced capture");
5059 return rc;
5060 }
5061 }
5062 }
5063 if ( mLongshotEnabled ) {
5064 rc = longShot();
5065 if (NO_ERROR != rc) {
5066 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5067 LOGE("Reprocess Deferred work failed");
5068 return UNKNOWN_ERROR;
5069 }
5070 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5071 LOGE("Jpeg Deferred work failed");
5072 return UNKNOWN_ERROR;
5073 }
5074 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5075 return rc;
5076 }
5077 }
5078 } else {
5079 LOGE("cannot add capture channel");
5080 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5081 return rc;
5082 }
5083 } else {
5084 // Stop Preview before taking NZSL snapshot
5085 stopPreview();
5086
5087 rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
5088 if (NO_ERROR != rc) {
5089 LOGE("Raw dimension update failed %d", rc);
5090 return rc;
5091 }
5092
5093 rc = declareSnapshotStreams();
5094 if (NO_ERROR != rc) {
5095 LOGE("RAW stream info configuration failed %d", rc);
5096 return rc;
5097 }
5098
5099 rc = addChannel(QCAMERA_CH_TYPE_RAW);
5100 if (rc == NO_ERROR) {
5101 // start postprocessor
5102 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5103 LOGE("Reprocess Deferred work failed");
5104 return UNKNOWN_ERROR;
5105 }
5106
5107 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5108 if (rc != NO_ERROR) {
5109 LOGE("cannot start postprocessor");
5110 delChannel(QCAMERA_CH_TYPE_RAW);
5111 return rc;
5112 }
5113
5114 rc = startChannel(QCAMERA_CH_TYPE_RAW);
5115 if (rc != NO_ERROR) {
5116 LOGE("cannot start raw channel");
5117 m_postprocessor.stop();
5118 delChannel(QCAMERA_CH_TYPE_RAW);
5119 return rc;
5120 }
5121 } else {
5122 LOGE("cannot add raw channel");
5123 return rc;
5124 }
5125 }
5126 }
5127
5128 //When take picture, stop sending preview callbacks to APP
5129 m_stateMachine.setPreviewCallbackNeeded(false);
5130 LOGI("X rc = %d", rc);
5131 return rc;
5132 }
5133
5134 /*===========================================================================
5135 * FUNCTION : configureOnlineRotation
5136 *
5137 * DESCRIPTION: Configure backend with expected rotation for snapshot stream
5138 *
5139 * PARAMETERS :
5140 * @ch : Channel containing a snapshot stream
5141 *
5142 * RETURN : int32_t type of status
5143 * NO_ERROR -- success
5144 * none-zero failure code
5145 *==========================================================================*/
configureOnlineRotation(QCameraChannel & ch)5146 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
5147 {
5148 int rc = NO_ERROR;
5149 uint32_t streamId = 0;
5150 QCameraStream *pStream = NULL;
5151
5152 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
5153 QCameraStream *stream = ch.getStreamByIndex(i);
5154 if ((NULL != stream) &&
5155 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
5156 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
5157 pStream = stream;
5158 break;
5159 }
5160 }
5161
5162 if (NULL == pStream) {
5163 LOGE("No snapshot stream found!");
5164 return BAD_VALUE;
5165 }
5166
5167 streamId = pStream->getMyServerID();
5168 // Update online rotation configuration
5169 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
5170 mParameters.getDeviceRotation());
5171 if (rc != NO_ERROR) {
5172 LOGE("addOnlineRotation failed %d", rc);
5173 return rc;
5174 }
5175
5176 return rc;
5177 }
5178
5179 /*===========================================================================
5180 * FUNCTION : declareSnapshotStreams
5181 *
5182 * DESCRIPTION: Configure backend with expected snapshot streams
5183 *
5184 * PARAMETERS : none
5185 *
5186 * RETURN : int32_t type of status
5187 * NO_ERROR -- success
5188 * none-zero failure code
5189 *==========================================================================*/
declareSnapshotStreams()5190 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
5191 {
5192 int rc = NO_ERROR;
5193
5194 // Update stream info configuration
5195 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
5196 if (rc != NO_ERROR) {
5197 LOGE("setStreamConfigure failed %d", rc);
5198 return rc;
5199 }
5200
5201 return rc;
5202 }
5203
5204 /*===========================================================================
5205 * FUNCTION : longShot
5206 *
5207 * DESCRIPTION: Queue one more ZSL frame
5208 * in the longshot pipe.
5209 *
5210 * PARAMETERS : none
5211 *
5212 * RETURN : int32_t type of status
5213 * NO_ERROR -- success
5214 * none-zero failure code
5215 *==========================================================================*/
longShot()5216 int32_t QCamera2HardwareInterface::longShot()
5217 {
5218 int32_t rc = NO_ERROR;
5219 uint8_t numSnapshots = mParameters.getNumOfSnapshots();
5220 QCameraPicChannel *pChannel = NULL;
5221
5222 if (mParameters.isZSLMode()) {
5223 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5224 } else {
5225 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5226 }
5227
5228 if (NULL != pChannel) {
5229 mm_camera_req_buf_t buf;
5230 memset(&buf, 0x0, sizeof(buf));
5231 buf.type = MM_CAMERA_REQ_SUPER_BUF;
5232 buf.num_buf_requested = numSnapshots;
5233 rc = pChannel->takePicture(&buf);
5234 } else {
5235 LOGE("Capture channel not initialized!");
5236 rc = NO_INIT;
5237 goto end;
5238 }
5239
5240 end:
5241 return rc;
5242 }
5243
5244 /*===========================================================================
5245 * FUNCTION : stopCaptureChannel
5246 *
5247 * DESCRIPTION: Stops capture channel
5248 *
5249 * PARAMETERS :
5250 * @destroy : Set to true to stop and delete camera channel.
5251 * Set to false to only stop capture channel.
5252 *
5253 * RETURN : int32_t type of status
5254 * NO_ERROR -- success
5255 * none-zero failure code
5256 *==========================================================================*/
stopCaptureChannel(bool destroy)5257 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
5258 {
5259 int rc = NO_ERROR;
5260 if (mParameters.isJpegPictureFormat() ||
5261 mParameters.isNV16PictureFormat() ||
5262 mParameters.isNV21PictureFormat()) {
5263 mParameters.setQuadraCfaMode(false, true);
5264 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5265 if (destroy && (NO_ERROR == rc)) {
5266 // Destroy camera channel but dont release context
5267 waitDeferredWork(mJpegJob);
5268 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
5269 }
5270 }
5271
5272 return rc;
5273 }
5274
5275 /*===========================================================================
5276 * FUNCTION : cancelPicture
5277 *
5278 * DESCRIPTION: cancel picture impl
5279 *
5280 * PARAMETERS : none
5281 *
5282 * RETURN : int32_t type of status
5283 * NO_ERROR -- success
5284 * none-zero failure code
5285 *==========================================================================*/
cancelPicture()5286 int QCamera2HardwareInterface::cancelPicture()
5287 {
5288 waitDeferredWork(mReprocJob);
5289 waitDeferredWork(mJpegJob);
5290
5291 //stop post processor
5292 m_postprocessor.stop();
5293
5294 unconfigureAdvancedCapture();
5295 LOGH("Enable display frames again");
5296 setDisplaySkip(FALSE);
5297
5298 if (mParameters.isZSLMode()) {
5299 QCameraPicChannel *pPicChannel = NULL;
5300 if (mParameters.getofflineRAW()) {
5301 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
5302 } else {
5303 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5304 }
5305 if (NULL != pPicChannel) {
5306 pPicChannel->cancelPicture();
5307 stopRAWChannel();
5308 stopAdvancedCapture(pPicChannel);
5309 }
5310 } else {
5311
5312 // normal capture case
5313 if (mParameters.isJpegPictureFormat() ||
5314 mParameters.isNV16PictureFormat() ||
5315 mParameters.isNV21PictureFormat()) {
5316 stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5317 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5318 } else {
5319 stopChannel(QCAMERA_CH_TYPE_RAW);
5320 delChannel(QCAMERA_CH_TYPE_RAW);
5321 }
5322 }
5323
5324 return NO_ERROR;
5325 }
5326
5327 /*===========================================================================
5328 * FUNCTION : captureDone
5329 *
5330 * DESCRIPTION: Function called when the capture is completed before encoding
5331 *
5332 * PARAMETERS : none
5333 *
5334 * RETURN : none
5335 *==========================================================================*/
captureDone()5336 void QCamera2HardwareInterface::captureDone()
5337 {
5338 qcamera_sm_internal_evt_payload_t *payload =
5339 (qcamera_sm_internal_evt_payload_t *)
5340 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
5341 if (NULL != payload) {
5342 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
5343 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
5344 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
5345 if (rc != NO_ERROR) {
5346 LOGE("processEvt ZSL capture done failed");
5347 free(payload);
5348 payload = NULL;
5349 }
5350 } else {
5351 LOGE("No memory for ZSL capture done event");
5352 }
5353 }
5354
5355 /*===========================================================================
5356 * FUNCTION : Live_Snapshot_thread
5357 *
5358 * DESCRIPTION: Seperate thread for taking live snapshot during recording
5359 *
5360 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5361 *
5362 * RETURN : none
5363 *==========================================================================*/
Live_Snapshot_thread(void * data)5364 void* Live_Snapshot_thread (void* data)
5365 {
5366
5367 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5368 if (!hw) {
5369 LOGE("take_picture_thread: NULL camera device");
5370 return (void *)BAD_VALUE;
5371 }
5372 if (hw->bLiveSnapshot) {
5373 hw->takeLiveSnapshot_internal();
5374 } else {
5375 hw->cancelLiveSnapshot_internal();
5376 }
5377 return (void* )NULL;
5378 }
5379
5380 /*===========================================================================
5381 * FUNCTION : Int_Pic_thread
5382 *
5383 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
5384 *
5385 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5386 *
5387 * RETURN : none
5388 *==========================================================================*/
Int_Pic_thread(void * data)5389 void* Int_Pic_thread (void* data)
5390 {
5391 int rc = NO_ERROR;
5392
5393 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5394
5395 if (!hw) {
5396 LOGE("take_picture_thread: NULL camera device");
5397 return (void *)BAD_VALUE;
5398 }
5399
5400 bool JpegMemOpt = false;
5401 char raw_format[PROPERTY_VALUE_MAX];
5402
5403 memset(raw_format, 0, sizeof(raw_format));
5404
5405 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
5406 if (rc == NO_ERROR) {
5407 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
5408 } else {
5409 //Snapshot attempt not successful, we need to do cleanup here
5410 hw->clearIntPendingEvents();
5411 }
5412
5413 return (void* )NULL;
5414 }
5415
5416 /*===========================================================================
5417 * FUNCTION : takeLiveSnapshot
5418 *
5419 * DESCRIPTION: take live snapshot during recording
5420 *
5421 * PARAMETERS : none
5422 *
5423 * RETURN : int32_t type of status
5424 * NO_ERROR -- success
5425 * none-zero failure code
5426 *==========================================================================*/
takeLiveSnapshot()5427 int QCamera2HardwareInterface::takeLiveSnapshot()
5428 {
5429 int rc = NO_ERROR;
5430 if (mLiveSnapshotThread != 0) {
5431 pthread_join(mLiveSnapshotThread,NULL);
5432 mLiveSnapshotThread = 0;
5433 }
5434 bLiveSnapshot = true;
5435 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5436 if (!rc) {
5437 pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
5438 }
5439 return rc;
5440 }
5441
5442 /*===========================================================================
5443 * FUNCTION : takePictureInternal
5444 *
5445 * DESCRIPTION: take snapshot triggered by backend
5446 *
5447 * PARAMETERS : none
5448 *
5449 * RETURN : int32_t type of status
5450 * NO_ERROR -- success
5451 * none-zero failure code
5452 *==========================================================================*/
takePictureInternal()5453 int QCamera2HardwareInterface::takePictureInternal()
5454 {
5455 int rc = NO_ERROR;
5456 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
5457 if (!rc) {
5458 pthread_setname_np(mIntPicThread, "CAM_IntPic");
5459 }
5460 return rc;
5461 }
5462
5463 /*===========================================================================
5464 * FUNCTION : checkIntPicPending
5465 *
5466 * DESCRIPTION: timed wait for jpeg completion event, and send
5467 * back completion event to backend
5468 *
5469 * PARAMETERS : none
5470 *
5471 * RETURN : none
5472 *==========================================================================*/
checkIntPicPending(bool JpegMemOpt,char * raw_format)5473 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
5474 {
5475 bool bSendToBackend = true;
5476 cam_int_evt_params_t params;
5477 int rc = NO_ERROR;
5478
5479 struct timespec ts;
5480 struct timeval tp;
5481 gettimeofday(&tp, NULL);
5482 ts.tv_sec = tp.tv_sec + 5;
5483 ts.tv_nsec = tp.tv_usec * 1000;
5484
5485 if (true == m_bIntJpegEvtPending ||
5486 (true == m_bIntRawEvtPending)) {
5487 //Waiting in HAL for snapshot taken notification
5488 pthread_mutex_lock(&m_int_lock);
5489 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
5490 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
5491 //Hit a timeout, or some spurious activity
5492 bSendToBackend = false;
5493 }
5494
5495 if (true == m_bIntJpegEvtPending) {
5496 params.event_type = 0;
5497 mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
5498 } else if (true == m_bIntRawEvtPending) {
5499 params.event_type = 1;
5500 mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
5501 }
5502 pthread_mutex_unlock(&m_int_lock);
5503
5504 if (true == m_bIntJpegEvtPending) {
5505 //Attempting to restart preview after taking JPEG snapshot
5506 lockAPI();
5507 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5508 unlockAPI();
5509 m_postprocessor.setJpegMemOpt(JpegMemOpt);
5510 } else if (true == m_bIntRawEvtPending) {
5511 //Attempting to restart preview after taking RAW snapshot
5512 stopChannel(QCAMERA_CH_TYPE_RAW);
5513 delChannel(QCAMERA_CH_TYPE_RAW);
5514 //restoring the old raw format
5515 property_set("persist.camera.raw.format", raw_format);
5516 }
5517
5518 if (true == bSendToBackend) {
5519 //send event back to server with the file path
5520 params.dim = m_postprocessor.m_dst_dim;
5521 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
5522 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
5523 params.size = mBackendFileSize;
5524 rc = mParameters.setIntEvent(params);
5525 }
5526
5527 clearIntPendingEvents();
5528 }
5529
5530 return;
5531 }
5532
5533 /*===========================================================================
5534 * FUNCTION : takeBackendPic_internal
5535 *
5536 * DESCRIPTION: take snapshot triggered by backend
5537 *
5538 * PARAMETERS : none
5539 *
5540 * RETURN : int32_t type of status
5541 * NO_ERROR -- success
5542 * none-zero failure code
5543 *==========================================================================*/
takeBackendPic_internal(bool * JpegMemOpt,char * raw_format)5544 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
5545 {
5546 int rc = NO_ERROR;
5547 qcamera_api_result_t apiResult;
5548
5549 lockAPI();
5550 //Set rotation value from user settings as Jpeg rotation
5551 //to configure back-end modules.
5552 mParameters.setJpegRotation(mParameters.getRotation());
5553
5554 setRetroPicture(0);
5555 /* Prepare snapshot in case LED needs to be flashed */
5556 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
5557 // Start Preparing for normal Frames
5558 LOGH("Start Prepare Snapshot");
5559 /* Prepare snapshot in case LED needs to be flashed */
5560 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
5561 if (rc == NO_ERROR) {
5562 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
5563 rc = apiResult.status;
5564 }
5565 LOGH("Prep Snapshot done rc = %d", rc);
5566 mPrepSnapRun = true;
5567 }
5568 unlockAPI();
5569
5570 if (true == m_bIntJpegEvtPending) {
5571 //Attempting to take JPEG snapshot
5572 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5573 LOGE("Init PProc Deferred work failed");
5574 return UNKNOWN_ERROR;
5575 }
5576 *JpegMemOpt = m_postprocessor.getJpegMemOpt();
5577 m_postprocessor.setJpegMemOpt(false);
5578
5579 /* capture */
5580 lockAPI();
5581 LOGH("Capturing internal snapshot");
5582 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
5583 if (rc == NO_ERROR) {
5584 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
5585 rc = apiResult.status;
5586 }
5587 unlockAPI();
5588 } else if (true == m_bIntRawEvtPending) {
5589 //Attempting to take RAW snapshot
5590 (void)JpegMemOpt;
5591 stopPreview();
5592
5593 //getting the existing raw format type
5594 property_get("persist.camera.raw.format", raw_format, "17");
5595 //setting it to a default know value for this task
5596 property_set("persist.camera.raw.format", "18");
5597
5598 rc = addChannel(QCAMERA_CH_TYPE_RAW);
5599 if (rc == NO_ERROR) {
5600 // start postprocessor
5601 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5602 LOGE("Init PProc Deferred work failed");
5603 return UNKNOWN_ERROR;
5604 }
5605 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5606 if (rc != NO_ERROR) {
5607 LOGE("cannot start postprocessor");
5608 delChannel(QCAMERA_CH_TYPE_RAW);
5609 return rc;
5610 }
5611
5612 rc = startChannel(QCAMERA_CH_TYPE_RAW);
5613 if (rc != NO_ERROR) {
5614 LOGE("cannot start raw channel");
5615 m_postprocessor.stop();
5616 delChannel(QCAMERA_CH_TYPE_RAW);
5617 return rc;
5618 }
5619 } else {
5620 LOGE("cannot add raw channel");
5621 return rc;
5622 }
5623 }
5624
5625 return rc;
5626 }
5627
5628 /*===========================================================================
5629 * FUNCTION : clearIntPendingEvents
5630 *
5631 * DESCRIPTION: clear internal pending events pertaining to backend
5632 * snapshot requests
5633 *
5634 * PARAMETERS : none
5635 *
5636 * RETURN : int32_t type of status
5637 * NO_ERROR -- success
5638 * none-zero failure code
5639 *==========================================================================*/
clearIntPendingEvents()5640 void QCamera2HardwareInterface::clearIntPendingEvents()
5641 {
5642 int rc = NO_ERROR;
5643
5644 if (true == m_bIntRawEvtPending) {
5645 preparePreview();
5646 startPreview();
5647 }
5648 if (true == m_bIntJpegEvtPending) {
5649 if (false == mParameters.isZSLMode()) {
5650 lockAPI();
5651 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
5652 unlockAPI();
5653 }
5654 }
5655
5656 pthread_mutex_lock(&m_int_lock);
5657 if (true == m_bIntJpegEvtPending) {
5658 m_bIntJpegEvtPending = false;
5659 } else if (true == m_bIntRawEvtPending) {
5660 m_bIntRawEvtPending = false;
5661 }
5662 pthread_mutex_unlock(&m_int_lock);
5663 return;
5664 }
5665
5666 /*===========================================================================
5667 * FUNCTION : takeLiveSnapshot_internal
5668 *
5669 * DESCRIPTION: take live snapshot during recording
5670 *
5671 * PARAMETERS : none
5672 *
5673 * RETURN : int32_t type of status
5674 * NO_ERROR -- success
5675 * none-zero failure code
5676 *==========================================================================*/
takeLiveSnapshot_internal()5677 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
5678 {
5679 int rc = NO_ERROR;
5680
5681 QCameraChannel *pChannel = NULL;
5682 QCameraChannel *pPreviewChannel = NULL;
5683 QCameraStream *pPreviewStream = NULL;
5684 QCameraStream *pStream = NULL;
5685
5686 //Set rotation value from user settings as Jpeg rotation
5687 //to configure back-end modules.
5688 mParameters.setJpegRotation(mParameters.getRotation());
5689
5690 // Configure advanced capture
5691 rc = configureAdvancedCapture();
5692 if (rc != NO_ERROR) {
5693 LOGE("Unsupported capture call");
5694 goto end;
5695 }
5696
5697 if (isLowPowerMode()) {
5698 pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
5699 } else {
5700 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5701 }
5702
5703 if (NULL == pChannel) {
5704 LOGE("Snapshot/Video channel not initialized");
5705 rc = NO_INIT;
5706 goto end;
5707 }
5708
5709 // Check if all preview buffers are mapped before creating
5710 // a jpeg session as preview stream buffers are queried during the same
5711 pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5712 if (pPreviewChannel != NULL) {
5713 uint32_t numStreams = pPreviewChannel->getNumOfStreams();
5714
5715 for (uint8_t i = 0 ; i < numStreams ; i++ ) {
5716 pStream = pPreviewChannel->getStreamByIndex(i);
5717 if (!pStream)
5718 continue;
5719 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5720 pPreviewStream = pStream;
5721 break;
5722 }
5723 }
5724
5725 if (pPreviewStream != NULL) {
5726 Mutex::Autolock l(mMapLock);
5727 QCameraMemory *pMemory = pStream->getStreamBufs();
5728 if (!pMemory) {
5729 LOGE("Error!! pMemory is NULL");
5730 return -ENOMEM;
5731 }
5732
5733 uint8_t waitCnt = 2;
5734 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
5735 LOGL(" Waiting for preview buffers to be mapped");
5736 mMapCond.waitRelative(
5737 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
5738 LOGL("Wait completed!!");
5739 waitCnt--;
5740 }
5741 // If all buffers are not mapped after retries, assert
5742 assert(pMemory->checkIfAllBuffersMapped());
5743 } else {
5744 assert(pPreviewStream);
5745 }
5746 }
5747
5748 DeferWorkArgs args;
5749 memset(&args, 0, sizeof(DeferWorkArgs));
5750
5751 args.pprocArgs = pChannel;
5752
5753 // No need to wait for mInitPProcJob here, because it was
5754 // queued in startPreview, and will definitely be processed before
5755 // mReprocJob can begin.
5756 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5757 args);
5758 if (mReprocJob == 0) {
5759 LOGE("Failed to queue CMD_DEF_PPROC_START");
5760 rc = -ENOMEM;
5761 goto end;
5762 }
5763
5764 // Create JPEG session
5765 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5766 args);
5767 if (mJpegJob == 0) {
5768 LOGE("Failed to queue CREATE_JPEG_SESSION");
5769 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5770 LOGE("Reprocess Deferred work was failed");
5771 }
5772 m_postprocessor.stop();
5773 rc = -ENOMEM;
5774 goto end;
5775 }
5776
5777 if (isLowPowerMode()) {
5778 mm_camera_req_buf_t buf;
5779 memset(&buf, 0x0, sizeof(buf));
5780 buf.type = MM_CAMERA_REQ_SUPER_BUF;
5781 buf.num_buf_requested = 1;
5782 rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
5783 goto end;
5784 }
5785
5786 //Disable reprocess for 4K liveshot case
5787 if (!mParameters.is4k2kVideoResolution()) {
5788 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
5789 if (rc != NO_ERROR) {
5790 LOGE("online rotation failed");
5791 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5792 LOGE("Reprocess Deferred work was failed");
5793 }
5794 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5795 LOGE("Jpeg Deferred work was failed");
5796 }
5797 m_postprocessor.stop();
5798 return rc;
5799 }
5800 }
5801
5802 if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
5803 QCameraStream *pStream = NULL;
5804 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5805 pStream = pChannel->getStreamByIndex(i);
5806 if ((NULL != pStream) &&
5807 (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
5808 break;
5809 }
5810 }
5811 if (pStream != NULL) {
5812 LOGD("REQUEST_FRAMES event for TNR snapshot");
5813 cam_stream_parm_buffer_t param;
5814 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
5815 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5816 param.frameRequest.enableStream = 1;
5817 rc = pStream->setParameter(param);
5818 if (rc != NO_ERROR) {
5819 LOGE("Stream Event REQUEST_FRAMES failed");
5820 }
5821 goto end;
5822 }
5823 }
5824
5825 // start snapshot channel
5826 if ((rc == NO_ERROR) && (NULL != pChannel)) {
5827 // Do not link metadata stream for 4K2k resolution
5828 // as CPP processing would be done on snapshot stream and not
5829 // reprocess stream
5830 if (!mParameters.is4k2kVideoResolution()) {
5831 // Find and try to link a metadata stream from preview channel
5832 QCameraChannel *pMetaChannel = NULL;
5833 QCameraStream *pMetaStream = NULL;
5834 QCameraStream *pPreviewStream = NULL;
5835
5836 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
5837 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5838 uint32_t streamNum = pMetaChannel->getNumOfStreams();
5839 QCameraStream *pStream = NULL;
5840 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
5841 pStream = pMetaChannel->getStreamByIndex(i);
5842 if (NULL != pStream) {
5843 if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
5844 pMetaStream = pStream;
5845 } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType())
5846 && (!mParameters.isHfrMode())) {
5847 // Do not link preview stream for HFR live snapshot.
5848 // Thumbnail will not be derived from preview for HFR live snapshot.
5849 pPreviewStream = pStream;
5850 }
5851 }
5852 }
5853 }
5854
5855 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
5856 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
5857 if (NO_ERROR != rc) {
5858 LOGE("Metadata stream link failed %d", rc);
5859 }
5860 }
5861 if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
5862 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
5863 if (NO_ERROR != rc) {
5864 LOGE("Preview stream link failed %d", rc);
5865 }
5866 }
5867 }
5868 rc = pChannel->start();
5869 }
5870
5871 end:
5872 if (rc != NO_ERROR) {
5873 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
5874 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
5875 }
5876 return rc;
5877 }
5878
5879 /*===========================================================================
5880 * FUNCTION : cancelLiveSnapshot
5881 *
5882 * DESCRIPTION: cancel current live snapshot request
5883 *
5884 * PARAMETERS : none
5885 *
5886 * RETURN : int32_t type of status
5887 * NO_ERROR -- success
5888 * none-zero failure code
5889 *==========================================================================*/
cancelLiveSnapshot()5890 int QCamera2HardwareInterface::cancelLiveSnapshot()
5891 {
5892 int rc = NO_ERROR;
5893 if (mLiveSnapshotThread != 0) {
5894 pthread_join(mLiveSnapshotThread,NULL);
5895 mLiveSnapshotThread = 0;
5896 }
5897 bLiveSnapshot = false;
5898 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5899 if (!rc) {
5900 pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap");
5901 }
5902 return rc;
5903 }
5904
5905 /*===========================================================================
5906 * FUNCTION : cancelLiveSnapshot_internal
5907 *
5908 * DESCRIPTION: cancel live snapshot during recording
5909 *
5910 * PARAMETERS : none
5911 *
5912 * RETURN : int32_t type of status
5913 * NO_ERROR -- success
5914 * none-zero failure code
5915 *==========================================================================*/
cancelLiveSnapshot_internal()5916 int QCamera2HardwareInterface::cancelLiveSnapshot_internal() {
5917 int rc = NO_ERROR;
5918
5919 unconfigureAdvancedCapture();
5920 LOGH("Enable display frames again");
5921 setDisplaySkip(FALSE);
5922
5923 //stop post processor
5924 m_postprocessor.stop();
5925
5926 // stop snapshot channel
5927 if (!mParameters.isTNRSnapshotEnabled()) {
5928 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
5929 } else {
5930 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5931 if (NULL != pChannel) {
5932 QCameraStream *pStream = NULL;
5933 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5934 pStream = pChannel->getStreamByIndex(i);
5935 if ((NULL != pStream) &&
5936 (CAM_STREAM_TYPE_SNAPSHOT ==
5937 pStream->getMyType())) {
5938 break;
5939 }
5940 }
5941 if (pStream != NULL) {
5942 LOGD("REQUEST_FRAMES event for TNR snapshot");
5943 cam_stream_parm_buffer_t param;
5944 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
5945 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5946 param.frameRequest.enableStream = 0;
5947 rc = pStream->setParameter(param);
5948 if (rc != NO_ERROR) {
5949 LOGE("Stream Event REQUEST_FRAMES failed");
5950 }
5951 }
5952 }
5953 }
5954
5955 return rc;
5956 }
5957
5958 /*===========================================================================
5959 * FUNCTION : putParameters
5960 *
5961 * DESCRIPTION: put parameters string impl
5962 *
5963 * PARAMETERS :
5964 * @parms : parameters string to be released
5965 *
5966 * RETURN : int32_t type of status
5967 * NO_ERROR -- success
5968 * none-zero failure code
5969 *==========================================================================*/
putParameters(char * parms)5970 int QCamera2HardwareInterface::putParameters(char *parms)
5971 {
5972 free(parms);
5973 return NO_ERROR;
5974 }
5975
5976 /*===========================================================================
5977 * FUNCTION : sendCommand
5978 *
5979 * DESCRIPTION: send command impl
5980 *
5981 * PARAMETERS :
5982 * @command : command to be executed
5983 * @arg1 : optional argument 1
5984 * @arg2 : optional argument 2
5985 *
5986 * RETURN : int32_t type of status
5987 * NO_ERROR -- success
5988 * none-zero failure code
5989 *==========================================================================*/
sendCommand(int32_t command,__unused int32_t & arg1,__unused int32_t & arg2)5990 int QCamera2HardwareInterface::sendCommand(int32_t command,
5991 __unused int32_t &arg1, __unused int32_t &arg2)
5992 {
5993 int rc = NO_ERROR;
5994
5995 switch (command) {
5996 #ifndef VANILLA_HAL
5997 case CAMERA_CMD_LONGSHOT_ON:
5998 arg1 = arg2 = 0;
5999 // Longshot can only be enabled when image capture
6000 // is not active.
6001 if ( !m_stateMachine.isCaptureRunning() ) {
6002 LOGI("Longshot Enabled");
6003 mLongshotEnabled = true;
6004 rc = mParameters.setLongshotEnable(mLongshotEnabled);
6005
6006 // Due to recent buffer count optimizations
6007 // ZSL might run with considerably less buffers
6008 // when not in longshot mode. Preview needs to
6009 // restart in this case.
6010 if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
6011 QCameraChannel *pChannel = NULL;
6012 QCameraStream *pSnapStream = NULL;
6013 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6014 if (NULL != pChannel) {
6015 QCameraStream *pStream = NULL;
6016 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
6017 pStream = pChannel->getStreamByIndex(i);
6018 if (pStream != NULL) {
6019 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
6020 pSnapStream = pStream;
6021 break;
6022 }
6023 }
6024 }
6025 if (NULL != pSnapStream) {
6026 uint8_t required = 0;
6027 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
6028 if (pSnapStream->getBufferCount() < required) {
6029 // We restart here, to reset the FPS and no
6030 // of buffers as per the requirement of longshot usecase.
6031 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
6032 if (getRelatedCamSyncInfo()->sync_control ==
6033 CAM_SYNC_RELATED_SENSORS_ON) {
6034 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
6035 }
6036 }
6037 }
6038 }
6039 }
6040 //
6041 mPrepSnapRun = false;
6042 mCACDoneReceived = FALSE;
6043 } else {
6044 rc = NO_INIT;
6045 }
6046 break;
6047 case CAMERA_CMD_LONGSHOT_OFF:
6048 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
6049 cancelPicture();
6050 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
6051 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6052 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
6053 mCameraHandle->ops->stop_zsl_snapshot(
6054 mCameraHandle->camera_handle,
6055 pZSLChannel->getMyHandle());
6056 }
6057 }
6058 mPrepSnapRun = false;
6059 LOGI("Longshot Disabled");
6060 mLongshotEnabled = false;
6061 rc = mParameters.setLongshotEnable(mLongshotEnabled);
6062 mCACDoneReceived = FALSE;
6063 break;
6064 case CAMERA_CMD_HISTOGRAM_ON:
6065 case CAMERA_CMD_HISTOGRAM_OFF:
6066 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
6067 LOGH("Histogram -> %s",
6068 mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
6069 break;
6070 #endif
6071 case CAMERA_CMD_START_FACE_DETECTION:
6072 case CAMERA_CMD_STOP_FACE_DETECTION:
6073 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6074 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6075 LOGH("FaceDetection -> %s",
6076 mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
6077 break;
6078 #ifndef VANILLA_HAL
6079 case CAMERA_CMD_HISTOGRAM_SEND_DATA:
6080 #endif
6081 default:
6082 rc = NO_ERROR;
6083 break;
6084 }
6085 return rc;
6086 }
6087
6088 /*===========================================================================
6089 * FUNCTION : registerFaceImage
6090 *
6091 * DESCRIPTION: register face image impl
6092 *
6093 * PARAMETERS :
6094 * @img_ptr : ptr to image buffer
6095 * @config : ptr to config struct about input image info
6096 * @faceID : [OUT] face ID to uniquely identifiy the registered face image
6097 *
6098 * RETURN : int32_t type of status
6099 * NO_ERROR -- success
6100 * none-zero failure code
6101 *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)6102 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
6103 cam_pp_offline_src_config_t *config,
6104 int32_t &faceID)
6105 {
6106 int rc = NO_ERROR;
6107 faceID = -1;
6108
6109 if (img_ptr == NULL || config == NULL) {
6110 LOGE("img_ptr or config is NULL");
6111 return BAD_VALUE;
6112 }
6113
6114 // allocate ion memory for source image
6115 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
6116 if (imgBuf == NULL) {
6117 LOGE("Unable to new heap memory obj for image buf");
6118 return NO_MEMORY;
6119 }
6120
6121 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE);
6122 if (rc < 0) {
6123 LOGE("Unable to allocate heap memory for image buf");
6124 delete imgBuf;
6125 return NO_MEMORY;
6126 }
6127
6128 void *pBufPtr = imgBuf->getPtr(0);
6129 if (pBufPtr == NULL) {
6130 LOGE("image buf is NULL");
6131 imgBuf->deallocate();
6132 delete imgBuf;
6133 return NO_MEMORY;
6134 }
6135 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
6136 //Do cache ops before sending for reprocess
6137 imgBuf->cacheOps(0, ION_IOC_CLEAN_INV_CACHES);
6138
6139 cam_pp_feature_config_t pp_feature;
6140 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
6141 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
6142 QCameraReprocessChannel *pChannel =
6143 addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
6144
6145 if (pChannel == NULL) {
6146 LOGE("fail to add offline reprocess channel");
6147 imgBuf->deallocate();
6148 delete imgBuf;
6149 return UNKNOWN_ERROR;
6150 }
6151
6152 rc = pChannel->start();
6153 if (rc != NO_ERROR) {
6154 LOGE("Cannot start reprocess channel");
6155 imgBuf->deallocate();
6156 delete imgBuf;
6157 delete pChannel;
6158 return rc;
6159 }
6160
6161 ssize_t bufSize = imgBuf->getSize(0);
6162 if (BAD_INDEX != bufSize) {
6163 rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0),
6164 (size_t)bufSize, faceID);
6165 } else {
6166 LOGE("Failed to retrieve buffer size (bad index)");
6167 return UNKNOWN_ERROR;
6168 }
6169
6170 // done with register face image, free imgbuf and delete reprocess channel
6171 imgBuf->deallocate();
6172 delete imgBuf;
6173 imgBuf = NULL;
6174 pChannel->stop();
6175 delete pChannel;
6176 pChannel = NULL;
6177
6178 return rc;
6179 }
6180
6181 /*===========================================================================
6182 * FUNCTION : release
6183 *
6184 * DESCRIPTION: release camera resource impl
6185 *
6186 * PARAMETERS : none
6187 *
6188 * RETURN : int32_t type of status
6189 * NO_ERROR -- success
6190 * none-zero failure code
6191 *==========================================================================*/
release()6192 int QCamera2HardwareInterface::release()
6193 {
6194 // stop and delete all channels
6195 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
6196 if (m_channels[i] != NULL) {
6197 stopChannel((qcamera_ch_type_enum_t)i);
6198 delChannel((qcamera_ch_type_enum_t)i);
6199 }
6200 }
6201
6202 return NO_ERROR;
6203 }
6204
6205 /*===========================================================================
6206 * FUNCTION : dump
6207 *
6208 * DESCRIPTION: camera status dump impl
6209 *
6210 * PARAMETERS :
6211 * @fd : fd for the buffer to be dumped with camera status
6212 *
6213 * RETURN : int32_t type of status
6214 * NO_ERROR -- success
6215 * none-zero failure code
6216 *==========================================================================*/
dump(int fd)6217 int QCamera2HardwareInterface::dump(int fd)
6218 {
6219 dprintf(fd, "\n Camera HAL information Begin \n");
6220 dprintf(fd, "Camera ID: %d \n", mCameraId);
6221 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
6222 dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
6223 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
6224 dprintf(fd, "\n Camera HAL information End \n");
6225
6226 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
6227 debug level property */
6228 mParameters.updateDebugLevel();
6229 return NO_ERROR;
6230 }
6231
6232 /*===========================================================================
6233 * FUNCTION : processAPI
6234 *
6235 * DESCRIPTION: process API calls from upper layer
6236 *
6237 * PARAMETERS :
6238 * @api : API to be processed
6239 * @api_payload : ptr to API payload if any
6240 *
6241 * RETURN : int32_t type of status
6242 * NO_ERROR -- success
6243 * none-zero failure code
6244 *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)6245 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
6246 {
6247 int ret = DEAD_OBJECT;
6248
6249 if (m_smThreadActive) {
6250 ret = m_stateMachine.procAPI(api, api_payload);
6251 }
6252
6253 return ret;
6254 }
6255
6256 /*===========================================================================
6257 * FUNCTION : processEvt
6258 *
6259 * DESCRIPTION: process Evt from backend via mm-camera-interface
6260 *
6261 * PARAMETERS :
6262 * @evt : event type to be processed
6263 * @evt_payload : ptr to event payload if any
6264 *
6265 * RETURN : int32_t type of status
6266 * NO_ERROR -- success
6267 * none-zero failure code
6268 *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6269 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6270 {
6271 return m_stateMachine.procEvt(evt, evt_payload);
6272 }
6273
6274 /*===========================================================================
6275 * FUNCTION : processSyncEvt
6276 *
6277 * DESCRIPTION: process synchronous Evt from backend
6278 *
6279 * PARAMETERS :
6280 * @evt : event type to be processed
6281 * @evt_payload : ptr to event payload if any
6282 *
6283 * RETURN : int32_t type of status
6284 * NO_ERROR -- success
6285 * none-zero failure code
6286 *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6287 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6288 {
6289 int rc = NO_ERROR;
6290
6291 pthread_mutex_lock(&m_evtLock);
6292 rc = processEvt(evt, evt_payload);
6293 if (rc == NO_ERROR) {
6294 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
6295 while (m_evtResult.request_api != evt) {
6296 pthread_cond_wait(&m_evtCond, &m_evtLock);
6297 }
6298 rc = m_evtResult.status;
6299 }
6300 pthread_mutex_unlock(&m_evtLock);
6301
6302 return rc;
6303 }
6304
6305 /*===========================================================================
6306 * FUNCTION : evtHandle
6307 *
6308 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
6309 *
6310 * PARAMETERS :
6311 * @camera_handle : event type to be processed
6312 * @evt : ptr to event
6313 * @user_data : user data ptr
6314 *
6315 * RETURN : none
6316 *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)6317 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
6318 mm_camera_event_t *evt,
6319 void *user_data)
6320 {
6321 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
6322 if (obj && evt) {
6323 mm_camera_event_t *payload =
6324 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
6325 if (NULL != payload) {
6326 *payload = *evt;
6327 //peek into the event, if this is an eztune event from server,
6328 //then we don't need to post it to the SM Qs, we shud directly
6329 //spawn a thread and get the job done (jpeg or raw snapshot)
6330 switch (payload->server_event_type) {
6331 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
6332 //Received JPEG trigger from eztune
6333 if (false == obj->m_bIntJpegEvtPending) {
6334 pthread_mutex_lock(&obj->m_int_lock);
6335 obj->m_bIntJpegEvtPending = true;
6336 pthread_mutex_unlock(&obj->m_int_lock);
6337 obj->takePictureInternal();
6338 }
6339 free(payload);
6340 break;
6341 case CAM_EVENT_TYPE_INT_TAKE_RAW:
6342 //Received RAW trigger from eztune
6343 if (false == obj->m_bIntRawEvtPending) {
6344 pthread_mutex_lock(&obj->m_int_lock);
6345 obj->m_bIntRawEvtPending = true;
6346 pthread_mutex_unlock(&obj->m_int_lock);
6347 obj->takePictureInternal();
6348 }
6349 free(payload);
6350 break;
6351 case CAM_EVENT_TYPE_DAEMON_DIED:
6352 {
6353 Mutex::Autolock l(obj->mDefLock);
6354 obj->mDefCond.broadcast();
6355 LOGH("broadcast mDefCond signal\n");
6356 }
6357 default:
6358 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
6359 break;
6360 }
6361 }
6362 } else {
6363 LOGE("NULL user_data");
6364 }
6365 }
6366
6367 /*===========================================================================
6368 * FUNCTION : jpegEvtHandle
6369 *
6370 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
6371 *
6372 * PARAMETERS :
6373 * @status : status of jpeg job
6374 * @client_hdl: jpeg client handle
6375 * @jobId : jpeg job Id
6376 * @p_ouput : ptr to jpeg output result struct
6377 * @userdata : user data ptr
6378 *
6379 * RETURN : none
6380 *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)6381 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
6382 uint32_t /*client_hdl*/,
6383 uint32_t jobId,
6384 mm_jpeg_output_t *p_output,
6385 void *userdata)
6386 {
6387 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
6388 if (obj) {
6389 qcamera_jpeg_evt_payload_t *payload =
6390 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
6391 if (NULL != payload) {
6392 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
6393 payload->status = status;
6394 payload->jobId = jobId;
6395 if (p_output != NULL) {
6396 payload->out_data = *p_output;
6397 }
6398 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
6399 }
6400 } else {
6401 LOGE("NULL user_data");
6402 }
6403 }
6404
6405 /*===========================================================================
6406 * FUNCTION : thermalEvtHandle
6407 *
6408 * DESCRIPTION: routine to handle thermal event notification
6409 *
6410 * PARAMETERS :
6411 * @level : thermal level
6412 * @userdata : userdata passed in during registration
6413 * @data : opaque data from thermal client
6414 *
6415 * RETURN : int32_t type of status
6416 * NO_ERROR -- success
6417 * none-zero failure code
6418 *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t * level,void * userdata,void * data)6419 int QCamera2HardwareInterface::thermalEvtHandle(
6420 qcamera_thermal_level_enum_t *level, void *userdata, void *data)
6421 {
6422 if (!mCameraOpened) {
6423 LOGH("Camera is not opened, no need to handle thermal evt");
6424 return NO_ERROR;
6425 }
6426
6427 // Make sure thermal events are logged
6428 LOGH("level = %d, userdata = %p, data = %p",
6429 *level, userdata, data);
6430 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
6431 // becomes an aync call. This also means we can only pass payload
6432 // by value, not by address.
6433 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
6434 }
6435
6436 /*===========================================================================
6437 * FUNCTION : sendEvtNotify
6438 *
6439 * DESCRIPTION: send event notify to notify thread
6440 *
6441 * PARAMETERS :
6442 * @msg_type: msg type to be sent
6443 * @ext1 : optional extension1
6444 * @ext2 : optional extension2
6445 *
6446 * RETURN : int32_t type of status
6447 * NO_ERROR -- success
6448 * none-zero failure code
6449 *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)6450 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
6451 int32_t ext1,
6452 int32_t ext2)
6453 {
6454 qcamera_callback_argm_t cbArg;
6455 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6456 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
6457 cbArg.msg_type = msg_type;
6458 cbArg.ext1 = ext1;
6459 cbArg.ext2 = ext2;
6460 return m_cbNotifier.notifyCallback(cbArg);
6461 }
6462
6463 /*===========================================================================
6464 * FUNCTION : processAEInfo
6465 *
6466 * DESCRIPTION: process AE updates
6467 *
6468 * PARAMETERS :
6469 * @ae_params: current AE parameters
6470 *
6471 * RETURN : None
6472 *==========================================================================*/
processAEInfo(cam_3a_params_t & ae_params)6473 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
6474 {
6475 mParameters.updateAEInfo(ae_params);
6476 if (mParameters.isInstantAECEnabled()) {
6477 // Reset Instant AEC info only if instant aec enabled.
6478 bool bResetInstantAec = false;
6479 if (ae_params.settled) {
6480 // If AEC settled, reset instant AEC
6481 bResetInstantAec = true;
6482 } else if ((mParameters.isInstantCaptureEnabled()) &&
6483 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
6484 // if AEC not settled, and instant capture enabled,
6485 // reset instant AEC only when frame count is
6486 // more or equal to AEC frame bound value.
6487 bResetInstantAec = true;
6488 } else if ((mParameters.isInstantAECEnabled()) &&
6489 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
6490 // if AEC not settled, and only instant AEC enabled,
6491 // reset instant AEC only when frame count is
6492 // more or equal to AEC skip display frame bound value.
6493 bResetInstantAec = true;
6494 }
6495
6496 if (bResetInstantAec) {
6497 LOGD("setting instant AEC to false");
6498 mParameters.setInstantAEC(false, true);
6499 mInstantAecFrameCount = 0;
6500 }
6501 }
6502 return NO_ERROR;
6503 }
6504
6505 /*===========================================================================
6506 * FUNCTION : processFocusPositionInfo
6507 *
6508 * DESCRIPTION: process AF updates
6509 *
6510 * PARAMETERS :
6511 * @cur_pos_info: current lens position
6512 *
6513 * RETURN : None
6514 *==========================================================================*/
processFocusPositionInfo(cam_focus_pos_info_t & cur_pos_info)6515 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
6516 {
6517 mParameters.updateCurrentFocusPosition(cur_pos_info);
6518 return NO_ERROR;
6519 }
6520
6521 /*===========================================================================
6522 * FUNCTION : processAutoFocusEvent
6523 *
6524 * DESCRIPTION: process auto focus event
6525 *
6526 * PARAMETERS :
6527 * @focus_data: struct containing auto focus result info
6528 *
6529 * RETURN : int32_t type of status
6530 * NO_ERROR -- success
6531 * none-zero failure code
6532 *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)6533 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
6534 {
6535 int32_t ret = NO_ERROR;
6536 LOGH("E");
6537
6538 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
6539 // Ignore focus updates
6540 LOGH("X Secondary Camera, no need to process!! ");
6541 return ret;
6542 }
6543 cam_focus_mode_type focusMode = mParameters.getFocusMode();
6544 LOGH("[AF_DBG] focusMode=%d, focusState=%d isDepth=%d",
6545 focusMode, focus_data.focus_state, focus_data.isDepth);
6546
6547 switch (focusMode) {
6548 case CAM_FOCUS_MODE_AUTO:
6549 case CAM_FOCUS_MODE_MACRO:
6550 // ignore AF event if AF was already cancelled meanwhile
6551 if (!mActiveAF) {
6552 break;
6553 }
6554 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6555 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6556 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6557 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
6558 mActiveAF = false; // reset the mActiveAF in this special case
6559 break;
6560 }
6561
6562 //while transitioning from CAF->Auto/Macro, we might receive CAF related
6563 //events (PASSIVE_*) due to timing. Ignore such events if any.
6564 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
6565 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6566 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
6567 break;
6568 }
6569
6570 //This is just an intermediate update to HAL indicating focus is in progress. No need
6571 //to send this event to app. Same applies to INACTIVE state as well.
6572 if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
6573 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6574 break;
6575 }
6576 // update focus distance
6577 mParameters.updateFocusDistances(&focus_data.focus_dist);
6578
6579 //flush any old snapshot frames in ZSL Q which are not focused.
6580 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6581 QCameraPicChannel *pZSLChannel =
6582 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6583 if (NULL != pZSLChannel) {
6584 //flush the zsl-buffer
6585 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6586 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6587 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6588 }
6589 }
6590
6591 //send event to app finally
6592 LOGI("Send AF DOne event to app");
6593 ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6594 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
6595 break;
6596 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
6597 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
6598
6599 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6600 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6601 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6602 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
6603 mActiveAF = false; // reset the mActiveAF in this special case
6604 break;
6605 }
6606
6607 //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
6608 //process/wait for only ACTIVE_* events.
6609 if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6610 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6611 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
6612 break;
6613 }
6614
6615 if (!bDepthAFCallbacks && focus_data.isDepth &&
6616 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) {
6617 LOGD("Skip sending scan state to app, if depth focus");
6618 break;
6619 }
6620
6621 //These are the AF states for which we need to send notification to app in CAF mode.
6622 //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
6623 //AF is triggered while in CAF mode)
6624 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6625 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6626 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6627 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6628
6629 // update focus distance
6630 mParameters.updateFocusDistances(&focus_data.focus_dist);
6631
6632 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6633 QCameraPicChannel *pZSLChannel =
6634 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6635 if (NULL != pZSLChannel) {
6636 //flush the zsl-buffer
6637 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6638 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6639 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6640 }
6641 }
6642
6643 if (mActiveAF) {
6644 LOGI("Send AF Done event to app");
6645 }
6646 ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6647 ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6648 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
6649 }
6650 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
6651 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
6652 break;
6653 case CAM_FOCUS_MODE_INFINITY:
6654 case CAM_FOCUS_MODE_FIXED:
6655 case CAM_FOCUS_MODE_EDOF:
6656 default:
6657 LOGH("no ops for autofocus event in focusmode %d", focusMode);
6658 break;
6659 }
6660
6661 //Reset mActiveAF once we receive focus done event
6662 if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6663 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6664 mActiveAF = false;
6665 }
6666
6667 LOGH("X");
6668 return ret;
6669 }
6670
6671 /*===========================================================================
6672 * FUNCTION : processZoomEvent
6673 *
6674 * DESCRIPTION: process zoom event
6675 *
6676 * PARAMETERS :
6677 * @crop_info : crop info as a result of zoom operation
6678 *
6679 * RETURN : int32_t type of status
6680 * NO_ERROR -- success
6681 * none-zero failure code
6682 *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)6683 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
6684 {
6685 int32_t ret = NO_ERROR;
6686
6687 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6688 if (m_channels[i] != NULL) {
6689 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
6690 }
6691 }
6692 return ret;
6693 }
6694
6695 /*===========================================================================
6696 * FUNCTION : processZSLCaptureDone
6697 *
6698 * DESCRIPTION: process ZSL capture done events
6699 *
6700 * PARAMETERS : None
6701 *
6702 * RETURN : int32_t type of status
6703 * NO_ERROR -- success
6704 * none-zero failure code
6705 *==========================================================================*/
processZSLCaptureDone()6706 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
6707 {
6708 int rc = NO_ERROR;
6709
6710 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
6711 rc = unconfigureAdvancedCapture();
6712 }
6713
6714 return rc;
6715 }
6716
6717 /*===========================================================================
6718 * FUNCTION : processRetroAECUnlock
6719 *
6720 * DESCRIPTION: process retro burst AEC unlock events
6721 *
6722 * PARAMETERS : None
6723 *
6724 * RETURN : int32_t type of status
6725 * NO_ERROR -- success
6726 * none-zero failure code
6727 *==========================================================================*/
processRetroAECUnlock()6728 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
6729 {
6730 int rc = NO_ERROR;
6731
6732 LOGH("LED assisted AF Release AEC Lock");
6733 rc = mParameters.setAecLock("false");
6734 if (NO_ERROR != rc) {
6735 LOGE("Error setting AEC lock");
6736 return rc;
6737 }
6738
6739 rc = mParameters.commitParameters();
6740 if (NO_ERROR != rc) {
6741 LOGE("Error during camera parameter commit");
6742 } else {
6743 m_bLedAfAecLock = FALSE;
6744 }
6745
6746 return rc;
6747 }
6748
6749 /*===========================================================================
6750 * FUNCTION : processHDRData
6751 *
6752 * DESCRIPTION: process HDR scene events
6753 *
6754 * PARAMETERS :
6755 * @hdr_scene : HDR scene event data
6756 *
6757 * RETURN : int32_t type of status
6758 * NO_ERROR -- success
6759 * none-zero failure code
6760 *==========================================================================*/
processHDRData(__unused cam_asd_hdr_scene_data_t hdr_scene)6761 int32_t QCamera2HardwareInterface::processHDRData(
6762 __unused cam_asd_hdr_scene_data_t hdr_scene)
6763 {
6764 int rc = NO_ERROR;
6765
6766 #ifndef VANILLA_HAL
6767 if (hdr_scene.is_hdr_scene &&
6768 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
6769 mParameters.isAutoHDREnabled()) {
6770 m_HDRSceneEnabled = true;
6771 } else {
6772 m_HDRSceneEnabled = false;
6773 }
6774 mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
6775
6776 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6777
6778 size_t data_len = sizeof(int);
6779 size_t buffer_len = 1 *sizeof(int) //meta type
6780 + 1 *sizeof(int) //data len
6781 + 1 *sizeof(int); //data
6782 camera_memory_t *hdrBuffer = mGetMemory(-1,
6783 buffer_len,
6784 1,
6785 mCallbackCookie);
6786 if ( NULL == hdrBuffer ) {
6787 LOGE("Not enough memory for auto HDR data");
6788 return NO_MEMORY;
6789 }
6790
6791 int *pHDRData = (int *)hdrBuffer->data;
6792 if (pHDRData == NULL) {
6793 LOGE("memory data ptr is NULL");
6794 return UNKNOWN_ERROR;
6795 }
6796
6797 pHDRData[0] = CAMERA_META_DATA_HDR;
6798 pHDRData[1] = (int)data_len;
6799 pHDRData[2] = m_HDRSceneEnabled;
6800
6801 qcamera_callback_argm_t cbArg;
6802 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6803 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6804 cbArg.msg_type = CAMERA_MSG_META_DATA;
6805 cbArg.data = hdrBuffer;
6806 cbArg.user_data = hdrBuffer;
6807 cbArg.cookie = this;
6808 cbArg.release_cb = releaseCameraMemory;
6809 rc = m_cbNotifier.notifyCallback(cbArg);
6810 if (rc != NO_ERROR) {
6811 LOGE("fail sending auto HDR notification");
6812 hdrBuffer->release(hdrBuffer);
6813 }
6814 }
6815
6816 LOGH("hdr_scene_data: processHDRData: %d %f",
6817 hdr_scene.is_hdr_scene,
6818 hdr_scene.hdr_confidence);
6819
6820 #endif
6821 return rc;
6822 }
6823
6824 /*===========================================================================
6825 * FUNCTION : transAwbMetaToParams
6826 *
6827 * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
6828 *
6829 * PARAMETERS :
6830 * @awb_params : awb params from metadata callback
6831 *
6832 * RETURN : int32_t type of status
6833 * NO_ERROR -- success
6834 * none-zero failure code
6835 *==========================================================================*/
transAwbMetaToParams(cam_awb_params_t & awb_params)6836 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
6837 {
6838 mParameters.updateAWBParams(awb_params);
6839 return NO_ERROR;
6840 }
6841
6842 /*===========================================================================
6843 * FUNCTION : processPrepSnapshotDone
6844 *
6845 * DESCRIPTION: process prep snapshot done event
6846 *
6847 * PARAMETERS :
6848 * @prep_snapshot_state : state of prepare snapshot done. In other words,
6849 * i.e. whether need future frames for capture.
6850 *
6851 * RETURN : int32_t type of status
6852 * NO_ERROR -- success
6853 * none-zero failure code
6854 *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)6855 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
6856 cam_prep_snapshot_state_t prep_snapshot_state)
6857 {
6858 int32_t ret = NO_ERROR;
6859 LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
6860 prep_snapshot_state);
6861 if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
6862 prep_snapshot_state == NEED_FUTURE_FRAME) {
6863 LOGH("already handled in mm-camera-intf, no ops here");
6864 if (isRetroPicture()) {
6865 mParameters.setAecLock("true");
6866 mParameters.commitParameters();
6867 m_bLedAfAecLock = TRUE;
6868 }
6869 }
6870 return ret;
6871 }
6872
6873 /*===========================================================================
6874 * FUNCTION : processASDUpdate
6875 *
6876 * DESCRIPTION: process ASD update event
6877 *
6878 * PARAMETERS :
6879 * @scene: selected scene mode
6880 *
6881 * RETURN : int32_t type of status
6882 * NO_ERROR -- success
6883 * none-zero failure code
6884 *==========================================================================*/
processASDUpdate(__unused cam_asd_decision_t asd_decision)6885 int32_t QCamera2HardwareInterface::processASDUpdate(
6886 __unused cam_asd_decision_t asd_decision)
6887 {
6888 #ifndef VANILLA_HAL
6889 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6890 size_t data_len = sizeof(cam_auto_scene_t);
6891 size_t buffer_len = 1 *sizeof(int) //meta type
6892 + 1 *sizeof(int) //data len
6893 + data_len; //data
6894 camera_memory_t *asdBuffer = mGetMemory(-1,
6895 buffer_len, 1, mCallbackCookie);
6896 if ( NULL == asdBuffer ) {
6897 LOGE("Not enough memory for histogram data");
6898 return NO_MEMORY;
6899 }
6900
6901 int *pASDData = (int *)asdBuffer->data;
6902 if (pASDData == NULL) {
6903 LOGE("memory data ptr is NULL");
6904 return UNKNOWN_ERROR;
6905 }
6906
6907 pASDData[0] = CAMERA_META_DATA_ASD;
6908 pASDData[1] = (int)data_len;
6909 pASDData[2] = asd_decision.detected_scene;
6910
6911 qcamera_callback_argm_t cbArg;
6912 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6913 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6914 cbArg.msg_type = CAMERA_MSG_META_DATA;
6915 cbArg.data = asdBuffer;
6916 cbArg.user_data = asdBuffer;
6917 cbArg.cookie = this;
6918 cbArg.release_cb = releaseCameraMemory;
6919 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
6920 if (rc != NO_ERROR) {
6921 LOGE("fail sending notification");
6922 asdBuffer->release(asdBuffer);
6923 }
6924 }
6925 #endif
6926 return NO_ERROR;
6927 }
6928
6929 /*===========================================================================
6930 * FUNCTION : processJpegNotify
6931 *
6932 * DESCRIPTION: process jpeg event
6933 *
6934 * PARAMETERS :
6935 * @jpeg_evt: ptr to jpeg event payload
6936 *
6937 * RETURN : int32_t type of status
6938 * NO_ERROR -- success
6939 * none-zero failure code
6940 *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)6941 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
6942 {
6943 return m_postprocessor.processJpegEvt(jpeg_evt);
6944 }
6945
6946
6947 /*===========================================================================
6948 * FUNCTION : processDualCamFovControl
6949 *
6950 * DESCRIPTION: Based on the result collected from FOV control-
6951 * 1. Switch the master camera if needed
6952 * 2. Toggle the Low Power Mode for slave camera
6953 *
6954 * PARAMETERS : none
6955 *
6956 * RETURN : none
6957 *==========================================================================*/
processDualCamFovControl()6958 void QCamera2HardwareInterface::processDualCamFovControl()
6959 {
6960 uint32_t camState;
6961 fov_control_result_t fovControlResult;
6962
6963 if (!isDualCamera()) {
6964 return;
6965 }
6966
6967 fovControlResult = m_pFovControl->getFovControlResult();
6968
6969 camState = fovControlResult.activeCamState;
6970
6971 if (camState != mActiveCamera) {
6972 processCameraControl(camState);
6973 }
6974
6975 if (mMasterCamera != fovControlResult.camMasterPreview) {
6976 mMasterCamera = fovControlResult.camMasterPreview;
6977 switchCameraCb();
6978 }
6979 }
6980
6981 /*===========================================================================
6982 * FUNCTION : processCameraControl
6983 *
6984 * DESCRIPTION: Suspend and resume camera
6985 *
6986 * PARAMETERS :
6987 *
6988 * RETURN : int32_t type of status
6989 * NO_ERROR -- success
6990 * none-zero failure code
6991 *==========================================================================*/
processCameraControl(uint32_t camState)6992 int32_t QCamera2HardwareInterface::processCameraControl(uint32_t camState)
6993 {
6994 int32_t ret = NO_ERROR;
6995
6996 //Set camera controls to parameter and back-end
6997 ret = mParameters.setCameraControls(camState);
6998
6999 //Update camera status to internal channel
7000 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7001 if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7002 ret = m_channels[i]->processCameraControl(camState);
7003 if (ret != NO_ERROR) {
7004 LOGE("Channel Switch Failed");
7005 break;
7006 }
7007 }
7008 }
7009 if (ret == NO_ERROR) {
7010 if (camState == MM_CAMERA_TYPE_MAIN) {
7011 m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle);
7012 } else if (camState == MM_CAMERA_TYPE_AUX) {
7013 m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle);
7014 }
7015 }
7016 LOGH("mActiveCamera = %d to %d", mActiveCamera, camState);
7017 mActiveCamera = camState;
7018 return ret;
7019 }
7020
7021 /*===========================================================================
7022 * FUNCTION : switchCameraCb
7023 *
7024 * DESCRIPTION: switch camera's in case of dual camera
7025 *
7026 * PARAMETERS :
7027 *
7028 * RETURN : int32_t type of status
7029 * NO_ERROR -- success
7030 * none-zero failure code
7031 *==========================================================================*/
switchCameraCb()7032 int32_t QCamera2HardwareInterface::switchCameraCb()
7033 {
7034 int32_t ret = NO_ERROR;
7035
7036 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7037 if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7038 ret = m_channels[i]->switchChannelCb();
7039 if (ret != NO_ERROR) {
7040 LOGE("Channel Switch Failed");
7041 break;
7042 }
7043 }
7044 }
7045
7046 if (ret == NO_ERROR && mActiveCamera == MM_CAMERA_DUAL_CAM) {
7047 //Trigger Event to modules to update Master info
7048 mParameters.setSwitchCamera();
7049
7050 //Change active handle
7051 if (get_aux_camera_handle(mCameraHandle->camera_handle)
7052 == m_ActiveHandle) {
7053 m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle);
7054 } else if (get_main_camera_handle(mCameraHandle->camera_handle)
7055 == m_ActiveHandle) {
7056 m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle);
7057 } else {
7058 m_ActiveHandle = mCameraHandle->camera_handle;
7059 }
7060 }
7061 return ret;
7062 }
7063
7064 /*===========================================================================
7065 * FUNCTION : lockAPI
7066 *
7067 * DESCRIPTION: lock to process API
7068 *
7069 * PARAMETERS : none
7070 *
7071 * RETURN : none
7072 *==========================================================================*/
lockAPI()7073 void QCamera2HardwareInterface::lockAPI()
7074 {
7075 pthread_mutex_lock(&m_lock);
7076 }
7077
7078 /*===========================================================================
7079 * FUNCTION : waitAPIResult
7080 *
7081 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
7082 * return only cerntain API event type arrives
7083 *
7084 * PARAMETERS :
7085 * @api_evt : API event type
7086 *
7087 * RETURN : none
7088 *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)7089 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
7090 qcamera_api_result_t *apiResult)
7091 {
7092 LOGD("wait for API result of evt (%d)", api_evt);
7093 int resultReceived = 0;
7094 while (!resultReceived) {
7095 pthread_cond_wait(&m_cond, &m_lock);
7096 if (m_apiResultList != NULL) {
7097 api_result_list *apiResultList = m_apiResultList;
7098 api_result_list *apiResultListPrevious = m_apiResultList;
7099 while (apiResultList != NULL) {
7100 if (apiResultList->result.request_api == api_evt) {
7101 resultReceived = 1;
7102 *apiResult = apiResultList->result;
7103 apiResultListPrevious->next = apiResultList->next;
7104 if (apiResultList == m_apiResultList) {
7105 m_apiResultList = apiResultList->next;
7106 }
7107 free(apiResultList);
7108 break;
7109 }
7110 else {
7111 apiResultListPrevious = apiResultList;
7112 apiResultList = apiResultList->next;
7113 }
7114 }
7115 }
7116 }
7117 LOGD("return (%d) from API result wait for evt (%d)",
7118 apiResult->status, api_evt);
7119 }
7120
7121
7122 /*===========================================================================
7123 * FUNCTION : unlockAPI
7124 *
7125 * DESCRIPTION: API processing is done, unlock
7126 *
7127 * PARAMETERS : none
7128 *
7129 * RETURN : none
7130 *==========================================================================*/
unlockAPI()7131 void QCamera2HardwareInterface::unlockAPI()
7132 {
7133 pthread_mutex_unlock(&m_lock);
7134 }
7135
7136 /*===========================================================================
7137 * FUNCTION : signalAPIResult
7138 *
7139 * DESCRIPTION: signal condition viarable that cerntain API event type arrives
7140 *
7141 * PARAMETERS :
7142 * @result : API result
7143 *
7144 * RETURN : none
7145 *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)7146 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
7147 {
7148
7149 pthread_mutex_lock(&m_lock);
7150 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
7151 if (apiResult == NULL) {
7152 LOGE("ERROR: malloc for api result failed, Result will not be sent");
7153 goto malloc_failed;
7154 }
7155 apiResult->result = *result;
7156 apiResult->next = NULL;
7157 if (m_apiResultList == NULL) m_apiResultList = apiResult;
7158 else {
7159 api_result_list *apiResultList = m_apiResultList;
7160 while(apiResultList->next != NULL) apiResultList = apiResultList->next;
7161 apiResultList->next = apiResult;
7162 }
7163 malloc_failed:
7164 pthread_cond_broadcast(&m_cond);
7165 pthread_mutex_unlock(&m_lock);
7166 }
7167
7168 /*===========================================================================
7169 * FUNCTION : signalEvtResult
7170 *
7171 * DESCRIPTION: signal condition variable that certain event was processed
7172 *
7173 * PARAMETERS :
7174 * @result : Event result
7175 *
7176 * RETURN : none
7177 *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)7178 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
7179 {
7180 pthread_mutex_lock(&m_evtLock);
7181 m_evtResult = *result;
7182 pthread_cond_signal(&m_evtCond);
7183 pthread_mutex_unlock(&m_evtLock);
7184 }
7185
prepareRawStream(QCameraChannel * curChannel)7186 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
7187 {
7188 int32_t rc = NO_ERROR;
7189 cam_dimension_t str_dim,max_dim;
7190 QCameraChannel *pChannel;
7191
7192 max_dim.width = 0;
7193 max_dim.height = 0;
7194
7195 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
7196 if (m_channels[j] != NULL) {
7197 pChannel = m_channels[j];
7198 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
7199 QCameraStream *pStream = pChannel->getStreamByIndex(i);
7200 if (pStream != NULL) {
7201 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7202 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7203 continue;
7204 }
7205 pStream->getFrameDimension(str_dim);
7206 if (str_dim.width > max_dim.width) {
7207 max_dim.width = str_dim.width;
7208 }
7209 if (str_dim.height > max_dim.height) {
7210 max_dim.height = str_dim.height;
7211 }
7212 }
7213 }
7214 }
7215 }
7216
7217 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
7218 QCameraStream *pStream = curChannel->getStreamByIndex(i);
7219 if (pStream != NULL) {
7220 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7221 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7222 continue;
7223 }
7224 pStream->getFrameDimension(str_dim);
7225 if (str_dim.width > max_dim.width) {
7226 max_dim.width = str_dim.width;
7227 }
7228 if (str_dim.height > max_dim.height) {
7229 max_dim.height = str_dim.height;
7230 }
7231 }
7232 }
7233 rc = mParameters.updateRAW(max_dim);
7234 return rc;
7235 }
7236
7237 /*===========================================================================
7238 * FUNCTION : addStreamToChannel
7239 *
7240 * DESCRIPTION: add a stream into a channel
7241 *
7242 * PARAMETERS :
7243 * @pChannel : ptr to channel obj
7244 * @streamType : type of stream to be added
7245 * @streamCB : callback of stream
7246 * @userData : user data ptr to callback
7247 *
7248 * RETURN : int32_t type of status
7249 * NO_ERROR -- success
7250 * none-zero failure code
7251 *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)7252 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
7253 cam_stream_type_t streamType,
7254 stream_cb_routine streamCB,
7255 void *userData)
7256 {
7257 int32_t rc = NO_ERROR;
7258 QCameraHeapMemory *pStreamInfo = NULL;
7259
7260 if (streamType == CAM_STREAM_TYPE_RAW) {
7261 prepareRawStream(pChannel);
7262 }
7263
7264 pStreamInfo = allocateStreamInfoBuf(streamType, getStreamRefCount(streamType));
7265 if (pStreamInfo == NULL) {
7266 LOGE("no mem for stream info buf");
7267 return NO_MEMORY;
7268 }
7269
7270 bool bDynAllocBuf = false;
7271 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
7272 bDynAllocBuf = true;
7273 }
7274
7275 cam_padding_info_t padding_info;
7276
7277 if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
7278 cam_analysis_info_t analysisInfo;
7279 cam_feature_mask_t featureMask;
7280
7281 featureMask = 0;
7282 mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask);
7283 rc = mParameters.getAnalysisInfo(
7284 ((mParameters.getRecordingHintValue() == true) &&
7285 mParameters.fdModeInVideo()),
7286 FALSE,
7287 featureMask,
7288 &analysisInfo);
7289 if (rc != NO_ERROR) {
7290 LOGE("getAnalysisInfo failed, ret = %d", rc);
7291 return rc;
7292 }
7293
7294 padding_info = analysisInfo.analysis_padding_info;
7295 } else {
7296 padding_info =
7297 gCamCapability[mCameraId]->padding_info;
7298 if (streamType == CAM_STREAM_TYPE_PREVIEW || streamType == CAM_STREAM_TYPE_POSTVIEW) {
7299 padding_info.width_padding = mSurfaceStridePadding;
7300 padding_info.height_padding = CAM_PAD_TO_2;
7301 }
7302 if((!needReprocess())
7303 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
7304 || (!mParameters.isLLNoiseEnabled())) {
7305 padding_info.offset_info.offset_x = 0;
7306 padding_info.offset_info.offset_y = 0;
7307 }
7308 }
7309
7310 bool deferAllocation = needDeferred(streamType);
7311 LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
7312 deferAllocation, bDynAllocBuf, streamType);
7313 rc = pChannel->addStream(*this,
7314 pStreamInfo,
7315 NULL,
7316 &padding_info,
7317 streamCB, userData,
7318 bDynAllocBuf,
7319 deferAllocation);
7320
7321 if (rc != NO_ERROR) {
7322 LOGE("add stream type (%d) failed, ret = %d",
7323 streamType, rc);
7324 return rc;
7325 }
7326
7327 return rc;
7328 }
7329
7330 /*===========================================================================
7331 * FUNCTION : addPreviewChannel
7332 *
7333 * DESCRIPTION: add a preview channel that contains a preview stream
7334 *
7335 * PARAMETERS : none
7336 *
7337 * RETURN : int32_t type of status
7338 * NO_ERROR -- success
7339 * none-zero failure code
7340 *==========================================================================*/
addPreviewChannel()7341 int32_t QCamera2HardwareInterface::addPreviewChannel()
7342 {
7343 int32_t rc = NO_ERROR;
7344 QCameraChannel *pChannel = NULL;
7345 char value[PROPERTY_VALUE_MAX];
7346 bool raw_yuv = false;
7347
7348
7349 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
7350 // if we had preview channel before, delete it first
7351 delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
7352 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
7353 }
7354
7355 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
7356 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7357 if (NULL == pChannel) {
7358 LOGE("no mem for preview channel");
7359 return NO_MEMORY;
7360 }
7361
7362 // preview only channel, don't need bundle attr and cb
7363 rc = pChannel->init(NULL, NULL, NULL);
7364 if (rc != NO_ERROR) {
7365 LOGE("init preview channel failed, ret = %d", rc);
7366 delete pChannel;
7367 return rc;
7368 }
7369
7370 // meta data stream always coexists with preview if applicable
7371 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7372 metadata_stream_cb_routine, this);
7373 if (rc != NO_ERROR) {
7374 LOGE("add metadata stream failed, ret = %d", rc);
7375 delete pChannel;
7376 return rc;
7377 }
7378
7379 if (isRdiMode()) {
7380 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7381 rdi_mode_stream_cb_routine, this);
7382 } else {
7383 if (isNoDisplayMode()) {
7384 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7385 nodisplay_preview_stream_cb_routine, this);
7386 } else {
7387 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7388 preview_stream_cb_routine, this);
7389 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7390 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7391 synchronous_stream_cb_routine);
7392 }
7393 }
7394 }
7395
7396 if (rc != NO_ERROR) {
7397 LOGE("add raw/preview stream failed, ret = %d", rc);
7398 delete pChannel;
7399 return rc;
7400 }
7401
7402 if (((mParameters.fdModeInVideo())
7403 || (mParameters.getDcrf() == true)
7404 || (mParameters.getRecordingHintValue() != true))
7405 && (!mParameters.isSecureMode())) {
7406 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7407 NULL, this);
7408 if (rc != NO_ERROR) {
7409 LOGE("add Analysis stream failed, ret = %d", rc);
7410 delete pChannel;
7411 return rc;
7412 }
7413 }
7414
7415 property_get("persist.camera.raw_yuv", value, "0");
7416 raw_yuv = atoi(value) > 0 ? true : false;
7417 if ( raw_yuv ) {
7418 rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
7419 preview_raw_stream_cb_routine,this);
7420 if ( rc != NO_ERROR ) {
7421 LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
7422 delete pChannel;
7423 return rc;
7424 }
7425 }
7426
7427 if (rc != NO_ERROR) {
7428 LOGE("add preview stream failed, ret = %d", rc);
7429 delete pChannel;
7430 return rc;
7431 }
7432
7433 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
7434 return rc;
7435 }
7436
7437 /*===========================================================================
7438 * FUNCTION : addVideoChannel
7439 *
7440 * DESCRIPTION: add a video channel that contains a video stream
7441 *
7442 * PARAMETERS : none
7443 *
7444 * RETURN : int32_t type of status
7445 * NO_ERROR -- success
7446 * none-zero failure code
7447 *==========================================================================*/
addVideoChannel()7448 int32_t QCamera2HardwareInterface::addVideoChannel()
7449 {
7450 int32_t rc = NO_ERROR;
7451 QCameraVideoChannel *pChannel = NULL;
7452
7453 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
7454 // if we had video channel before, delete it first
7455 delete m_channels[QCAMERA_CH_TYPE_VIDEO];
7456 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
7457 }
7458
7459 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
7460 pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
7461 if (NULL == pChannel) {
7462 LOGE("no mem for video channel");
7463 return NO_MEMORY;
7464 }
7465
7466 if (isLowPowerMode()) {
7467 mm_camera_channel_attr_t attr;
7468 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7469 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7470 attr.look_back = 0; //wait for future frame for liveshot
7471 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7472 attr.water_mark = 1; //hold min buffers possible in Q
7473 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7474 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7475 } else {
7476 // preview only channel, don't need bundle attr and cb
7477 rc = pChannel->init(NULL, NULL, NULL);
7478 }
7479
7480 if (rc != 0) {
7481 LOGE("init video channel failed, ret = %d", rc);
7482 delete pChannel;
7483 return rc;
7484 }
7485
7486 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
7487 video_stream_cb_routine, this);
7488
7489 if (rc != NO_ERROR) {
7490 LOGE("add video stream failed, ret = %d", rc);
7491 delete pChannel;
7492 return rc;
7493 }
7494
7495 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
7496 return rc;
7497 }
7498
7499 /*===========================================================================
7500 * FUNCTION : addSnapshotChannel
7501 *
7502 * DESCRIPTION: add a snapshot channel that contains a snapshot stream
7503 *
7504 * PARAMETERS : none
7505 *
7506 * RETURN : int32_t type of status
7507 * NO_ERROR -- success
7508 * none-zero failure code
7509 * NOTE : Add this channel for live snapshot usecase. Regular capture will
7510 * use addCaptureChannel.
7511 *==========================================================================*/
addSnapshotChannel()7512 int32_t QCamera2HardwareInterface::addSnapshotChannel()
7513 {
7514 int32_t rc = NO_ERROR;
7515 QCameraChannel *pChannel = NULL;
7516
7517 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
7518 // if we had ZSL channel before, delete it first
7519 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
7520 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
7521 }
7522
7523 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7524 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7525 if (NULL == pChannel) {
7526 LOGE("no mem for snapshot channel");
7527 return NO_MEMORY;
7528 }
7529
7530 mm_camera_channel_attr_t attr;
7531 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7532 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7533 attr.look_back = 0; //wait for future frame for liveshot
7534 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7535 attr.water_mark = 1; //hold min buffers possible in Q
7536 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7537 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
7538 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7539 if (rc != NO_ERROR) {
7540 LOGE("init snapshot channel failed, ret = %d", rc);
7541 delete pChannel;
7542 return rc;
7543 }
7544
7545 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7546 NULL, NULL);
7547 if (rc != NO_ERROR) {
7548 LOGE("add snapshot stream failed, ret = %d", rc);
7549 delete pChannel;
7550 return rc;
7551 }
7552
7553 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
7554 return rc;
7555 }
7556
7557 /*===========================================================================
7558 * FUNCTION : addRawChannel
7559 *
7560 * DESCRIPTION: add a raw channel that contains a raw image stream
7561 *
7562 * PARAMETERS : none
7563 *
7564 * RETURN : int32_t type of status
7565 * NO_ERROR -- success
7566 * none-zero failure code
7567 *==========================================================================*/
addRawChannel()7568 int32_t QCamera2HardwareInterface::addRawChannel()
7569 {
7570 int32_t rc = NO_ERROR;
7571 QCameraChannel *pChannel = NULL;
7572
7573 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
7574 // if we had raw channel before, delete it first
7575 delete m_channels[QCAMERA_CH_TYPE_RAW];
7576 m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
7577 }
7578
7579 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
7580 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7581 if (NULL == pChannel) {
7582 LOGE("no mem for raw channel");
7583 return NO_MEMORY;
7584 }
7585
7586 if (mParameters.getofflineRAW()) {
7587 mm_camera_channel_attr_t attr;
7588 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7589 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7590 attr.look_back = mParameters.getZSLBackLookCount();
7591 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7592 attr.water_mark = 1;
7593 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7594 rc = pChannel->init(&attr, raw_channel_cb_routine, this);
7595 if (rc != NO_ERROR) {
7596 LOGE("init RAW channel failed, ret = %d", rc);
7597 delete pChannel;
7598 return rc;
7599 }
7600 } else {
7601 rc = pChannel->init(NULL, NULL, NULL);
7602 if (rc != NO_ERROR) {
7603 LOGE("init raw channel failed, ret = %d", rc);
7604 delete pChannel;
7605 return rc;
7606 }
7607 }
7608
7609 if (!mParameters.isZSLMode()) {
7610 // meta data stream always coexists with snapshot in regular RAW capture case
7611 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7612 metadata_stream_cb_routine, this);
7613 if (rc != NO_ERROR) {
7614 LOGE("add metadata stream failed, ret = %d", rc);
7615 delete pChannel;
7616 return rc;
7617 }
7618 }
7619
7620 if (mParameters.getofflineRAW()) {
7621 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7622 NULL, this);
7623 } else {
7624 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7625 raw_stream_cb_routine, this);
7626 }
7627 if (rc != NO_ERROR) {
7628 LOGE("add snapshot stream failed, ret = %d", rc);
7629 delete pChannel;
7630 return rc;
7631 }
7632 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
7633 return rc;
7634 }
7635
7636 /*===========================================================================
7637 * FUNCTION : addZSLChannel
7638 *
7639 * DESCRIPTION: add a ZSL channel that contains a preview stream and
7640 * a snapshot stream
7641 *
7642 * PARAMETERS : none
7643 *
7644 * RETURN : int32_t type of status
7645 * NO_ERROR -- success
7646 * none-zero failure code
7647 *==========================================================================*/
addZSLChannel()7648 int32_t QCamera2HardwareInterface::addZSLChannel()
7649 {
7650 int32_t rc = NO_ERROR;
7651 QCameraPicChannel *pChannel = NULL;
7652 char value[PROPERTY_VALUE_MAX];
7653 bool raw_yuv = false;
7654
7655 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
7656 // if we had ZSL channel before, delete it first
7657 delete m_channels[QCAMERA_CH_TYPE_ZSL];
7658 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
7659 }
7660
7661 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
7662 pChannel = new QCameraPicChannel(handle,
7663 mCameraHandle->ops);
7664 if (NULL == pChannel) {
7665 LOGE("no mem for ZSL channel");
7666 return NO_MEMORY;
7667 }
7668
7669 // ZSL channel, init with bundle attr and cb
7670 mm_camera_channel_attr_t attr;
7671 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7672 if (mParameters.isSceneSelectionEnabled()) {
7673 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7674 } else {
7675 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7676 }
7677 attr.look_back = mParameters.getZSLBackLookCount();
7678 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7679 if (mParameters.isOEMFeatEnabled()) {
7680 attr.post_frame_skip++;
7681 }
7682 attr.water_mark = mParameters.getZSLQueueDepth();
7683 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7684 attr.user_expected_frame_id =
7685 mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
7686
7687 //Enabled matched queue
7688 if (isFrameSyncEnabled()) {
7689 LOGH("Enabling frame sync for dual camera, camera Id: %d",
7690 mCameraId);
7691 attr.enable_frame_sync = 1;
7692 }
7693 rc = pChannel->init(&attr,
7694 zsl_channel_cb,
7695 this);
7696 if (rc != 0) {
7697 LOGE("init ZSL channel failed, ret = %d", rc);
7698 delete pChannel;
7699 return rc;
7700 }
7701
7702 // meta data stream always coexists with preview if applicable
7703 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7704 metadata_stream_cb_routine, this);
7705 if (rc != NO_ERROR) {
7706 LOGE("add metadata stream failed, ret = %d", rc);
7707 delete pChannel;
7708 return rc;
7709 }
7710
7711 if (isNoDisplayMode()) {
7712 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7713 nodisplay_preview_stream_cb_routine, this);
7714 } else {
7715 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7716 preview_stream_cb_routine, this);
7717 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7718 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7719 synchronous_stream_cb_routine);
7720 }
7721 }
7722 if (rc != NO_ERROR) {
7723 LOGE("add preview stream failed, ret = %d", rc);
7724 delete pChannel;
7725 return rc;
7726 }
7727
7728 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7729 NULL, this);
7730 if (rc != NO_ERROR) {
7731 LOGE("add snapshot stream failed, ret = %d", rc);
7732 delete pChannel;
7733 return rc;
7734 }
7735
7736 if (!mParameters.isSecureMode()) {
7737 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7738 NULL, this);
7739 if (rc != NO_ERROR) {
7740 LOGE("add Analysis stream failed, ret = %d", rc);
7741 delete pChannel;
7742 return rc;
7743 }
7744 }
7745
7746 property_get("persist.camera.raw_yuv", value, "0");
7747 raw_yuv = atoi(value) > 0 ? true : false;
7748 if (raw_yuv) {
7749 rc = addStreamToChannel(pChannel,
7750 CAM_STREAM_TYPE_RAW,
7751 preview_raw_stream_cb_routine,
7752 this);
7753 if (rc != NO_ERROR) {
7754 LOGE("add raw stream failed, ret = %d", rc);
7755 delete pChannel;
7756 return rc;
7757 }
7758 }
7759
7760 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
7761 return rc;
7762 }
7763
7764 /*===========================================================================
7765 * FUNCTION : addCaptureChannel
7766 *
7767 * DESCRIPTION: add a capture channel that contains a snapshot stream
7768 * and a postview stream
7769 *
7770 * PARAMETERS : none
7771 *
7772 * RETURN : int32_t type of status
7773 * NO_ERROR -- success
7774 * none-zero failure code
7775 * NOTE : Add this channel for regular capture usecase.
7776 * For Live snapshot usecase, use addSnapshotChannel.
7777 *==========================================================================*/
addCaptureChannel()7778 int32_t QCamera2HardwareInterface::addCaptureChannel()
7779 {
7780 int32_t rc = NO_ERROR;
7781 QCameraPicChannel *pChannel = NULL;
7782 char value[PROPERTY_VALUE_MAX];
7783 bool raw_yuv = false;
7784
7785 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
7786 delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
7787 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
7788 }
7789
7790 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
7791 pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
7792 if (NULL == pChannel) {
7793 LOGE("no mem for capture channel");
7794 return NO_MEMORY;
7795 }
7796
7797 // Capture channel, only need snapshot and postview streams start together
7798 mm_camera_channel_attr_t attr;
7799 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7800 if ( mLongshotEnabled ) {
7801 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7802 attr.look_back = mParameters.getZSLBackLookCount();
7803 attr.water_mark = mParameters.getZSLQueueDepth();
7804 } else {
7805 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7806 }
7807 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7808
7809 rc = pChannel->init(&attr,
7810 capture_channel_cb_routine,
7811 this);
7812 if (rc != NO_ERROR) {
7813 LOGE("init capture channel failed, ret = %d", rc);
7814 delete pChannel;
7815 return rc;
7816 }
7817
7818 // meta data stream always coexists with snapshot in regular capture case
7819 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7820 metadata_stream_cb_routine, this);
7821 if (rc != NO_ERROR) {
7822 LOGE("add metadata stream failed, ret = %d", rc);
7823 delete pChannel;
7824 return rc;
7825 }
7826
7827 if (mLongshotEnabled) {
7828 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7829 preview_stream_cb_routine, this);
7830 if (rc != NO_ERROR) {
7831 LOGE("add preview stream failed, ret = %d", rc);
7832 delete pChannel;
7833 return rc;
7834 }
7835 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7836 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7837 synchronous_stream_cb_routine);
7838 }
7839 //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
7840 } else if (!mParameters.getQuadraCfa()) {
7841 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
7842 NULL, this);
7843 if (rc != NO_ERROR) {
7844 LOGE("add postview stream failed, ret = %d", rc);
7845 delete pChannel;
7846 return rc;
7847 }
7848 }
7849
7850 if (!mParameters.getofflineRAW()) {
7851 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7852 NULL, this);
7853 if (rc != NO_ERROR) {
7854 LOGE("add snapshot stream failed, ret = %d", rc);
7855 delete pChannel;
7856 return rc;
7857 }
7858 }
7859
7860 stream_cb_routine stream_cb = NULL;
7861 property_get("persist.camera.raw_yuv", value, "0");
7862 raw_yuv = atoi(value) > 0 ? true : false;
7863
7864 if (raw_yuv) {
7865 stream_cb = snapshot_raw_stream_cb_routine;
7866 }
7867
7868 if ((raw_yuv) || (mParameters.getofflineRAW())) {
7869 rc = addStreamToChannel(pChannel,
7870 CAM_STREAM_TYPE_RAW, stream_cb, this);
7871 if (rc != NO_ERROR) {
7872 LOGE("add raw stream failed, ret = %d", rc);
7873 delete pChannel;
7874 return rc;
7875 }
7876 }
7877
7878 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
7879 return rc;
7880 }
7881
7882 /*===========================================================================
7883 * FUNCTION : addMetaDataChannel
7884 *
7885 * DESCRIPTION: add a meta data channel that contains a metadata stream
7886 *
7887 * PARAMETERS : none
7888 *
7889 * RETURN : int32_t type of status
7890 * NO_ERROR -- success
7891 * none-zero failure code
7892 *==========================================================================*/
addMetaDataChannel()7893 int32_t QCamera2HardwareInterface::addMetaDataChannel()
7894 {
7895 int32_t rc = NO_ERROR;
7896 QCameraChannel *pChannel = NULL;
7897
7898 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
7899 delete m_channels[QCAMERA_CH_TYPE_METADATA];
7900 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
7901 }
7902
7903 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
7904 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7905 if (NULL == pChannel) {
7906 LOGE("no mem for metadata channel");
7907 return NO_MEMORY;
7908 }
7909
7910 rc = pChannel->init(NULL,
7911 NULL,
7912 NULL);
7913 if (rc != NO_ERROR) {
7914 LOGE("init metadata channel failed, ret = %d", rc);
7915 delete pChannel;
7916 return rc;
7917 }
7918
7919 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7920 metadata_stream_cb_routine, this);
7921 if (rc != NO_ERROR) {
7922 LOGE("add metadata stream failed, ret = %d", rc);
7923 delete pChannel;
7924 return rc;
7925 }
7926
7927 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
7928 return rc;
7929 }
7930
7931 /*===========================================================================
7932 * FUNCTION : addCallbackChannel
7933 *
7934 * DESCRIPTION: add a callback channel that contains a callback stream
7935 *
7936 * PARAMETERS : none
7937 *
7938 * RETURN : int32_t type of status
7939 * NO_ERROR -- success
7940 * none-zero failure code
7941 *==========================================================================*/
addCallbackChannel()7942 int32_t QCamera2HardwareInterface::addCallbackChannel()
7943 {
7944 int32_t rc = NO_ERROR;
7945 QCameraChannel *pChannel = NULL;
7946
7947 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
7948 delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
7949 m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
7950 }
7951
7952 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
7953 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7954 if (NULL == pChannel) {
7955 LOGE("no mem for callback channel");
7956 return NO_MEMORY;
7957 }
7958
7959 rc = pChannel->init(NULL, NULL, this);
7960 if (rc != NO_ERROR) {
7961 LOGE("init callback channel failed, ret = %d",
7962 rc);
7963 delete pChannel;
7964 return rc;
7965 }
7966
7967 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
7968 callback_stream_cb_routine, this);
7969 if (rc != NO_ERROR) {
7970 LOGE("add callback stream failed, ret = %d", rc);
7971 delete pChannel;
7972 return rc;
7973 }
7974
7975 m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
7976 return rc;
7977 }
7978
7979
7980 /*===========================================================================
7981 * FUNCTION : addAnalysisChannel
7982 *
7983 * DESCRIPTION: add a analysis channel that contains a analysis stream
7984 *
7985 * PARAMETERS : none
7986 *
7987 * RETURN : int32_t type of status
7988 * NO_ERROR -- success
7989 * none-zero failure code
7990 *==========================================================================*/
addAnalysisChannel()7991 int32_t QCamera2HardwareInterface::addAnalysisChannel()
7992 {
7993 int32_t rc = NO_ERROR;
7994 QCameraChannel *pChannel = NULL;
7995
7996 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
7997 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
7998 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
7999 }
8000
8001 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
8002 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8003 if (NULL == pChannel) {
8004 LOGE("no mem for metadata channel");
8005 return NO_MEMORY;
8006 }
8007
8008 rc = pChannel->init(NULL, NULL, this);
8009 if (rc != NO_ERROR) {
8010 LOGE("init Analysis channel failed, ret = %d", rc);
8011 delete pChannel;
8012 return rc;
8013 }
8014
8015 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
8016 NULL, this);
8017 if (rc != NO_ERROR) {
8018 LOGE("add Analysis stream failed, ret = %d", rc);
8019 delete pChannel;
8020 return rc;
8021 }
8022
8023 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
8024 return rc;
8025 }
8026
8027
8028 /*===========================================================================
8029 * FUNCTION : getPPConfig
8030 *
8031 * DESCRIPTION: get Post processing configaration data
8032 *
8033 * PARAMETERS :
8034 * @pp config: pp config structure pointer,
8035 * @curIndex: current pp channel index
8036 * @multipass: Flag if multipass prcessing enabled.
8037 *
8038 * RETURN : int32_t type of status
8039 * NO_ERROR -- success
8040 * none-zero failure code
8041 *==========================================================================*/
getPPConfig(cam_pp_feature_config_t & pp_config,int8_t curIndex,bool multipass)8042 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
8043 int8_t curIndex, bool multipass)
8044 {
8045 int32_t rc = NO_ERROR;
8046 int32_t feature_set = 0;
8047
8048 if (multipass) {
8049 LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
8050 mParameters.getReprocCount(), curIndex);
8051 }
8052
8053 LOGH("Supported pproc feature mask = %llx",
8054 gCamCapability[mCameraId]->qcom_supported_feature_mask);
8055 cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
8056 int32_t zoomLevel = mParameters.getParmZoomLevel();
8057 uint32_t rotation = mParameters.getJpegRotation();
8058 int32_t effect = mParameters.getEffectValue();
8059
8060 pp_config.cur_reproc_count = curIndex + 1;
8061 pp_config.total_reproc_count = mParameters.getReprocCount();
8062
8063 //Checking what feature mask to enable
8064 if (curIndex == 0) {
8065 if (mParameters.getQuadraCfa()) {
8066 feature_set = 2;
8067 } else {
8068 feature_set = 0;
8069 }
8070 } else if (curIndex == 1) {
8071 if (mParameters.getQuadraCfa()) {
8072 feature_set = 0;
8073 } else {
8074 feature_set = 1;
8075 }
8076 }
8077
8078 switch(feature_set) {
8079 case 0:
8080 //Configure feature mask for first pass of reprocessing
8081 //check if any effects are enabled
8082 if ((CAM_EFFECT_MODE_OFF != effect) &&
8083 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
8084 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
8085 pp_config.effect = effect;
8086 }
8087
8088 //check for features that need to be enabled by default like sharpness
8089 //(if supported by hw).
8090 if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
8091 !mParameters.isOptiZoomEnabled()) {
8092 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
8093 pp_config.sharpness = mParameters.getSharpness();
8094 }
8095
8096 //check if zoom is enabled
8097 if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
8098 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8099 }
8100
8101 if (mParameters.isWNREnabled() &&
8102 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
8103 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
8104 pp_config.denoise2d.denoise_enable = 1;
8105 pp_config.denoise2d.process_plates =
8106 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
8107 }
8108
8109 if (isCACEnabled()) {
8110 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
8111 }
8112
8113 //check if rotation is required
8114 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8115 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8116 if (rotation == 0) {
8117 pp_config.rotation = ROTATE_0;
8118 } else if (rotation == 90) {
8119 pp_config.rotation = ROTATE_90;
8120 } else if (rotation == 180) {
8121 pp_config.rotation = ROTATE_180;
8122 } else if (rotation == 270) {
8123 pp_config.rotation = ROTATE_270;
8124 }
8125 }
8126
8127 if (mParameters.isHDREnabled()){
8128 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
8129 pp_config.hdr_param.hdr_enable = 1;
8130 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
8131 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
8132 } else {
8133 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8134 pp_config.hdr_param.hdr_enable = 0;
8135 }
8136
8137 //check if scaling is enabled
8138 if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
8139 mParameters.isReprocScaleEnabled() &&
8140 mParameters.isUnderReprocScaling()){
8141 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8142 mParameters.getPicSizeFromAPK(
8143 pp_config.scale_param.output_width,
8144 pp_config.scale_param.output_height);
8145 }
8146
8147 if(mParameters.isUbiFocusEnabled()) {
8148 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
8149 } else {
8150 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
8151 }
8152
8153 if(mParameters.isUbiRefocus()) {
8154 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
8155 pp_config.misc_buf_param.misc_buffer_index = 0;
8156 } else {
8157 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
8158 }
8159
8160 if(mParameters.isChromaFlashEnabled()) {
8161 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
8162 pp_config.flash_value = CAM_FLASH_ON;
8163 } else {
8164 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
8165 }
8166
8167 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
8168 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
8169 pp_config.zoom_level = (uint8_t) zoomLevel;
8170 } else {
8171 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
8172 }
8173
8174 if (mParameters.getofflineRAW()) {
8175 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
8176 }
8177
8178 if (mParameters.isTruePortraitEnabled()) {
8179 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
8180 pp_config.misc_buf_param.misc_buffer_index = 0;
8181 } else {
8182 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
8183 }
8184
8185 if(mParameters.isStillMoreEnabled()) {
8186 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
8187 } else {
8188 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
8189 }
8190
8191 if (mParameters.isOEMFeatEnabled()) {
8192 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
8193 }
8194
8195 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8196 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8197 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8198 } else {
8199 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8200 }
8201 }
8202
8203 if ((multipass) &&
8204 (m_postprocessor.getPPChannelCount() > 1)
8205 && (!mParameters.getQuadraCfa())) {
8206 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
8207 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
8208 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
8209 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
8210 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8211 } else {
8212 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8213 }
8214
8215 cam_dimension_t thumb_src_dim;
8216 cam_dimension_t thumb_dst_dim;
8217 mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
8218 mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
8219 if ((thumb_dst_dim.width != thumb_src_dim.width) ||
8220 (thumb_dst_dim.height != thumb_src_dim.height)) {
8221 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
8222 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8223 }
8224 }
8225
8226 break;
8227
8228 case 1:
8229 //Configure feature mask for second pass of reprocessing
8230 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
8231 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8232 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8233 if (rotation == 0) {
8234 pp_config.rotation = ROTATE_0;
8235 } else if (rotation == 90) {
8236 pp_config.rotation = ROTATE_90;
8237 } else if (rotation == 180) {
8238 pp_config.rotation = ROTATE_180;
8239 } else if (rotation == 270) {
8240 pp_config.rotation = ROTATE_270;
8241 }
8242 }
8243 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8244 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8245 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8246 } else {
8247 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8248 }
8249 }
8250 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
8251 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
8252 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_BYPASS;
8253 break;
8254
8255 case 2:
8256 //Setting feature for Quadra CFA
8257 pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
8258 break;
8259
8260 }
8261
8262 LOGH("pproc feature mask set = %llx pass count = %d",
8263 pp_config.feature_mask, curIndex);
8264 return rc;
8265 }
8266
8267 /*===========================================================================
8268 * FUNCTION : addReprocChannel
8269 *
8270 * DESCRIPTION: add a reprocess channel that will do reprocess on frames
8271 * coming from input channel
8272 *
8273 * PARAMETERS :
8274 * @pInputChannel : ptr to input channel whose frames will be post-processed
8275 * @cur_channel_index : Current channel index in multipass
8276 *
8277 * RETURN : Ptr to the newly created channel obj. NULL if failed.
8278 *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel,int8_t cur_channel_index)8279 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
8280 QCameraChannel *pInputChannel, int8_t cur_channel_index)
8281 {
8282 int32_t rc = NO_ERROR;
8283 QCameraReprocessChannel *pChannel = NULL;
8284 uint32_t burst_cnt = mParameters.getNumOfSnapshots();
8285 uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);
8286
8287 if (pInputChannel == NULL) {
8288 LOGE("input channel obj is NULL");
8289 return NULL;
8290 }
8291
8292 pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
8293 if (NULL == pChannel) {
8294 LOGE("no mem for reprocess channel");
8295 return NULL;
8296 }
8297
8298 // Capture channel, only need snapshot and postview streams start together
8299 mm_camera_channel_attr_t attr;
8300 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
8301 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
8302 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
8303 rc = pChannel->init(&attr,
8304 postproc_channel_cb_routine,
8305 this);
8306 if (rc != NO_ERROR) {
8307 LOGE("init reprocess channel failed, ret = %d", rc);
8308 delete pChannel;
8309 return NULL;
8310 }
8311
8312 // pp feature config
8313 cam_pp_feature_config_t pp_config;
8314 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
8315
8316 rc = getPPConfig(pp_config, cur_channel_index,
8317 ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
8318 if (rc != NO_ERROR){
8319 LOGE("Error while creating PP config");
8320 delete pChannel;
8321 return NULL;
8322 }
8323
8324 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
8325
8326 //WNR and HDR happen inline. No extra buffers needed.
8327 cam_feature_mask_t temp_feature_mask = pp_config.feature_mask;
8328 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8329 if (temp_feature_mask && mParameters.isHDREnabled()) {
8330 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
8331 }
8332
8333 if (mParameters.isStillMoreEnabled()) {
8334 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
8335 pp_config.burst_cnt = stillmore_config.burst_count;
8336 LOGH("Stillmore burst %d", pp_config.burst_cnt);
8337
8338 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
8339 // number of capture is already added. In the case of liveshot,
8340 // stillmore burst is 1. This is to account for the premature decrement
8341 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
8342 minStreamBufNum += 1;
8343 }
8344 }
8345
8346 if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
8347 minStreamBufNum += mParameters.getReprocCount() - 1;
8348 burst_cnt = mParameters.getReprocCount();
8349 if (cur_channel_index == 0) {
8350 pChannel->setReprocCount(2);
8351 } else {
8352 pChannel->setReprocCount(1);
8353 }
8354 } else {
8355 pChannel->setReprocCount(1);
8356 }
8357
8358 if (isDualCamera()) {
8359 minStreamBufNum += 1;
8360 }
8361
8362 // Add non inplace image lib buffers only when ppproc is present,
8363 // becuase pproc is non inplace and input buffers for img lib
8364 // are output for pproc and this number of extra buffers is required
8365 // If pproc is not there, input buffers for imglib are from snapshot stream
8366 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
8367 if (temp_feature_mask && imglib_extra_bufs) {
8368 // 1 is added because getNumOfExtraBuffersForImageProc returns extra
8369 // buffers assuming number of capture is already added
8370 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
8371 }
8372
8373 //Mask out features that are already processed in snapshot stream.
8374 cam_feature_mask_t snapshot_feature_mask = 0;
8375 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
8376
8377 pp_config.feature_mask &= ~snapshot_feature_mask;
8378 LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
8379 snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);
8380
8381 bool offlineReproc = needOfflineReprocessing();
8382 if (m_postprocessor.mOfflineDataBufs != NULL) {
8383 offlineReproc = TRUE;
8384 }
8385
8386 cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
8387 paddingInfo.offset_info.offset_x = 0;
8388 paddingInfo.offset_info.offset_y = 0;
8389 rc = pChannel->addReprocStreamsFromSource(*this,
8390 pp_config,
8391 pInputChannel,
8392 minStreamBufNum,
8393 burst_cnt,
8394 &paddingInfo,
8395 mParameters,
8396 mLongshotEnabled,
8397 offlineReproc);
8398 if (rc != NO_ERROR) {
8399 delete pChannel;
8400 return NULL;
8401 }
8402
8403 return pChannel;
8404 }
8405
8406 /*===========================================================================
8407 * FUNCTION : addOfflineReprocChannel
8408 *
8409 * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
8410 * that will do reprocess on frames coming from external images
8411 *
8412 * PARAMETERS :
8413 * @img_config : offline reporcess image info
8414 * @pp_feature : pp feature config
8415 *
8416 * RETURN : int32_t type of status
8417 * NO_ERROR -- success
8418 * none-zero failure code
8419 *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)8420 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
8421 cam_pp_offline_src_config_t &img_config,
8422 cam_pp_feature_config_t &pp_feature,
8423 stream_cb_routine stream_cb,
8424 void *userdata)
8425 {
8426 int32_t rc = NO_ERROR;
8427 QCameraReprocessChannel *pChannel = NULL;
8428
8429 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
8430 mCameraHandle->ops);
8431 if (NULL == pChannel) {
8432 LOGE("no mem for reprocess channel");
8433 return NULL;
8434 }
8435
8436 rc = pChannel->init(NULL, NULL, NULL);
8437 if (rc != NO_ERROR) {
8438 LOGE("init reprocess channel failed, ret = %d", rc);
8439 delete pChannel;
8440 return NULL;
8441 }
8442
8443 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
8444 if (pStreamInfo == NULL) {
8445 LOGE("no mem for stream info buf");
8446 delete pChannel;
8447 return NULL;
8448 }
8449
8450 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
8451 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
8452 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
8453 streamInfoBuf->fmt = img_config.input_fmt;
8454 streamInfoBuf->dim = img_config.input_dim;
8455 streamInfoBuf->buf_planes = img_config.input_buf_planes;
8456 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
8457 streamInfoBuf->num_of_burst = img_config.num_of_bufs;
8458
8459 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
8460 streamInfoBuf->reprocess_config.offline = img_config;
8461 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
8462 streamInfoBuf->num_bufs = img_config.num_of_bufs;
8463
8464 rc = pChannel->addStream(*this,
8465 pStreamInfo, NULL,
8466 &gCamCapability[mCameraId]->padding_info,
8467 stream_cb, userdata, false);
8468
8469 if (rc != NO_ERROR) {
8470 LOGE("add reprocess stream failed, ret = %d", rc);
8471 delete pChannel;
8472 return NULL;
8473 }
8474
8475 return pChannel;
8476 }
8477
8478 /*===========================================================================
8479 * FUNCTION : addChannel
8480 *
8481 * DESCRIPTION: add a channel by its type
8482 *
8483 * PARAMETERS :
8484 * @ch_type : channel type
8485 *
8486 * RETURN : int32_t type of status
8487 * NO_ERROR -- success
8488 * none-zero failure code
8489 *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)8490 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
8491 {
8492 int32_t rc = UNKNOWN_ERROR;
8493 switch (ch_type) {
8494 case QCAMERA_CH_TYPE_ZSL:
8495 rc = addZSLChannel();
8496 break;
8497 case QCAMERA_CH_TYPE_CAPTURE:
8498 rc = addCaptureChannel();
8499 break;
8500 case QCAMERA_CH_TYPE_PREVIEW:
8501 rc = addPreviewChannel();
8502 break;
8503 case QCAMERA_CH_TYPE_VIDEO:
8504 rc = addVideoChannel();
8505 break;
8506 case QCAMERA_CH_TYPE_SNAPSHOT:
8507 rc = addSnapshotChannel();
8508 break;
8509 case QCAMERA_CH_TYPE_RAW:
8510 rc = addRawChannel();
8511 break;
8512 case QCAMERA_CH_TYPE_METADATA:
8513 rc = addMetaDataChannel();
8514 break;
8515 case QCAMERA_CH_TYPE_CALLBACK:
8516 rc = addCallbackChannel();
8517 break;
8518 case QCAMERA_CH_TYPE_ANALYSIS:
8519 rc = addAnalysisChannel();
8520 break;
8521 default:
8522 break;
8523 }
8524 return rc;
8525 }
8526
8527 /*===========================================================================
8528 * FUNCTION : delChannel
8529 *
8530 * DESCRIPTION: delete a channel by its type
8531 *
8532 * PARAMETERS :
8533 * @ch_type : channel type
8534 * @destroy : delete context as well
8535 *
8536 * RETURN : int32_t type of status
8537 * NO_ERROR -- success
8538 * none-zero failure code
8539 *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)8540 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
8541 bool destroy)
8542 {
8543 if (m_channels[ch_type] != NULL) {
8544 if (destroy) {
8545 delete m_channels[ch_type];
8546 m_channels[ch_type] = NULL;
8547 } else {
8548 m_channels[ch_type]->deleteChannel();
8549 }
8550 }
8551
8552 return NO_ERROR;
8553 }
8554
8555 /*===========================================================================
8556 * FUNCTION : startChannel
8557 *
8558 * DESCRIPTION: start a channel by its type
8559 *
8560 * PARAMETERS :
8561 * @ch_type : channel type
8562 *
8563 * RETURN : int32_t type of status
8564 * NO_ERROR -- success
8565 * none-zero failure code
8566 *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)8567 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
8568 {
8569 int32_t rc = UNKNOWN_ERROR;
8570 if (m_channels[ch_type] != NULL) {
8571 rc = m_channels[ch_type]->start();
8572 }
8573 return rc;
8574 }
8575
8576 /*===========================================================================
8577 * FUNCTION : stopChannel
8578 *
8579 * DESCRIPTION: stop a channel by its type
8580 *
8581 * PARAMETERS :
8582 * @ch_type : channel type
8583 *
8584 * RETURN : int32_t type of status
8585 * NO_ERROR -- success
8586 * none-zero failure code
8587 *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)8588 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
8589 {
8590 int32_t rc = UNKNOWN_ERROR;
8591 if (m_channels[ch_type] != NULL) {
8592 rc = m_channels[ch_type]->stop();
8593 }
8594
8595 return rc;
8596 }
8597
8598 /*===========================================================================
8599 * FUNCTION : preparePreview
8600 *
8601 * DESCRIPTION: add channels needed for preview
8602 *
8603 * PARAMETERS : none
8604 *
8605 * RETURN : int32_t type of status
8606 * NO_ERROR -- success
8607 * none-zero failure code
8608 *==========================================================================*/
preparePreview()8609 int32_t QCamera2HardwareInterface::preparePreview()
8610 {
8611 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPAREPREVIEW);
8612 int32_t rc = NO_ERROR;
8613
8614 LOGI("E");
8615 rc = mParameters.setStreamConfigure(false, false, false);
8616 if (rc != NO_ERROR) {
8617 LOGE("setStreamConfigure failed %d", rc);
8618 return rc;
8619 }
8620
8621 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
8622 rc = addChannel(QCAMERA_CH_TYPE_ZSL);
8623 if (rc != NO_ERROR) {
8624 LOGE("failed!! rc = %d", rc);
8625 return rc;
8626 }
8627
8628 if (mParameters.isUBWCEnabled()) {
8629 cam_format_t fmt;
8630 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8631 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8632 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8633 if (rc != NO_ERROR) {
8634 delChannel(QCAMERA_CH_TYPE_ZSL);
8635 LOGE("failed!! rc = %d", rc);
8636 return rc;
8637 }
8638 }
8639 }
8640
8641 if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) {
8642 addChannel(QCAMERA_CH_TYPE_RAW);
8643 }
8644 } else {
8645 bool recordingHint = mParameters.getRecordingHintValue();
8646 if(!isRdiMode() && recordingHint) {
8647 //stop face detection,longshot,etc if turned ON in Camera mode
8648 #ifndef VANILLA_HAL
8649 int32_t arg; //dummy arg
8650 if (isLongshotEnabled()) {
8651 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
8652 }
8653 if (mParameters.isFaceDetectionEnabled()
8654 && (!mParameters.fdModeInVideo())) {
8655 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
8656 }
8657 if (mParameters.isHistogramEnabled()) {
8658 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
8659 }
8660 #endif
8661 //Don't create snapshot channel for liveshot, if low power mode is set.
8662 //Use video stream instead.
8663 if (!isLowPowerMode()) {
8664 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8665 if (rc != NO_ERROR) {
8666 return rc;
8667 }
8668 }
8669
8670 rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
8671 if (rc != NO_ERROR) {
8672 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8673 LOGE("failed!! rc = %d", rc);
8674 return rc;
8675 }
8676 }
8677
8678 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
8679 if (!isRdiMode() && (rc != NO_ERROR)) {
8680 if (recordingHint) {
8681 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8682 delChannel(QCAMERA_CH_TYPE_VIDEO);
8683 }
8684 }
8685
8686 if (mParameters.isUBWCEnabled() && !recordingHint) {
8687 cam_format_t fmt;
8688 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8689 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8690 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8691 if (rc != NO_ERROR) {
8692 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8693 if (!isRdiMode()) {
8694 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8695 delChannel(QCAMERA_CH_TYPE_VIDEO);
8696 }
8697 LOGE("failed!! rc = %d", rc);
8698 return rc;
8699 }
8700 }
8701 }
8702
8703 if (NO_ERROR != rc) {
8704 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8705 LOGE("failed!! rc = %d", rc);
8706 }
8707 }
8708
8709 LOGI("X rc = %d", rc);
8710 return rc;
8711 }
8712
8713 /*===========================================================================
8714 * FUNCTION : unpreparePreview
8715 *
8716 * DESCRIPTION: delete channels for preview
8717 *
8718 * PARAMETERS : none
8719 *
8720 * RETURN : none
8721 *==========================================================================*/
unpreparePreview()8722 void QCamera2HardwareInterface::unpreparePreview()
8723 {
8724 delChannel(QCAMERA_CH_TYPE_ZSL);
8725 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8726 delChannel(QCAMERA_CH_TYPE_VIDEO);
8727 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8728 delChannel(QCAMERA_CH_TYPE_CALLBACK);
8729 delChannel(QCAMERA_CH_TYPE_RAW);
8730 }
8731
8732 /*===========================================================================
8733 * FUNCTION : playShutter
8734 *
8735 * DESCRIPTION: send request to play shutter sound
8736 *
8737 * PARAMETERS : none
8738 *
8739 * RETURN : none
8740 *==========================================================================*/
playShutter()8741 void QCamera2HardwareInterface::playShutter(){
8742 if (mNotifyCb == NULL ||
8743 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
8744 LOGD("shutter msg not enabled or NULL cb");
8745 return;
8746 }
8747 LOGH("CAMERA_MSG_SHUTTER ");
8748 qcamera_callback_argm_t cbArg;
8749 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8750 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
8751 cbArg.msg_type = CAMERA_MSG_SHUTTER;
8752 cbArg.ext1 = 0;
8753 cbArg.ext2 = false;
8754 m_cbNotifier.notifyCallback(cbArg);
8755 }
8756
8757 /*===========================================================================
8758 * FUNCTION : getChannelByHandle
8759 *
8760 * DESCRIPTION: return a channel by its handle
8761 *
8762 * PARAMETERS :
8763 * @channelHandle : channel handle
8764 *
8765 * RETURN : a channel obj if found, NULL if not found
8766 *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)8767 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
8768 {
8769 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
8770 if (m_channels[i] != NULL &&
8771 (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
8772 return m_channels[i];
8773 }
8774 }
8775
8776 return NULL;
8777 }
8778 /*===========================================================================
8779 * FUNCTION : needPreviewFDCallback
8780 *
8781 * DESCRIPTION: decides if needPreviewFDCallback
8782 *
8783 * PARAMETERS :
8784 * @num_faces : number of faces
8785 *
8786 * RETURN : bool type of status
8787 * true -- success
8788 * fale -- failure code
8789 *==========================================================================*/
needPreviewFDCallback(uint8_t num_faces)8790 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
8791 {
8792 if (num_faces == 0 && mNumPreviewFaces == 0) {
8793 return false;
8794 }
8795
8796 return true;
8797 }
8798
8799 /*===========================================================================
8800 * FUNCTION : processFaceDetectionReuslt
8801 *
8802 * DESCRIPTION: process face detection reuslt
8803 *
8804 * PARAMETERS :
8805 * @faces_data : ptr to face processing result struct
8806 *
8807 * RETURN : int32_t type of status
8808 * NO_ERROR -- success
8809 * none-zero failure code
8810 *==========================================================================*/
processFaceDetectionResult(cam_faces_data_t * faces_data)8811 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
8812 {
8813 if (!mParameters.isFaceDetectionEnabled()) {
8814 LOGH("FaceDetection not enabled, no ops here");
8815 return NO_ERROR;
8816 }
8817
8818 qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
8819 cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
8820 if ((NULL == mDataCb) ||
8821 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
8822 (!needPreviewFDCallback(detect_data->num_faces_detected))
8823 #ifndef VANILLA_HAL
8824 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
8825 #endif
8826 ) {
8827 LOGH("metadata msgtype not enabled, no ops here");
8828 return NO_ERROR;
8829 }
8830
8831 if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
8832 // Don't send callback to app if this is skipped by fd at backend
8833 return NO_ERROR;
8834 }
8835
8836 cam_dimension_t display_dim;
8837 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
8838 if (display_dim.width <= 0 || display_dim.height <= 0) {
8839 LOGE("Invalid preview width or height (%d x %d)",
8840 display_dim.width, display_dim.height);
8841 return UNKNOWN_ERROR;
8842 }
8843
8844 // process face detection result
8845 // need separate face detection in preview or snapshot type
8846 size_t faceResultSize = 0;
8847 size_t data_len = 0;
8848 if(fd_type == QCAMERA_FD_PREVIEW){
8849 //fd for preview frames
8850 faceResultSize = sizeof(camera_frame_metadata_t);
8851 faceResultSize += sizeof(camera_face_t) * MAX_ROI;
8852 }else if(fd_type == QCAMERA_FD_SNAPSHOT){
8853 #ifndef VANILLA_HAL
8854 // fd for snapshot frames
8855 //check if face is detected in this frame
8856 if(detect_data->num_faces_detected > 0){
8857 data_len = sizeof(camera_frame_metadata_t) +
8858 sizeof(camera_face_t) * detect_data->num_faces_detected;
8859 }else{
8860 //no face
8861 data_len = 0;
8862 }
8863 #endif
8864 faceResultSize = 1 *sizeof(int) //meta data type
8865 + 1 *sizeof(int) // meta data len
8866 + data_len; //data
8867 }
8868
8869 camera_memory_t *faceResultBuffer = mGetMemory(-1,
8870 faceResultSize,
8871 1,
8872 mCallbackCookie);
8873 if ( NULL == faceResultBuffer ) {
8874 LOGE("Not enough memory for face result data");
8875 return NO_MEMORY;
8876 }
8877
8878 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
8879 memset(pFaceResult, 0, faceResultSize);
8880 unsigned char *faceData = NULL;
8881 if(fd_type == QCAMERA_FD_PREVIEW){
8882 faceData = pFaceResult;
8883 mNumPreviewFaces = detect_data->num_faces_detected;
8884 }else if(fd_type == QCAMERA_FD_SNAPSHOT){
8885 #ifndef VANILLA_HAL
8886 //need fill meta type and meta data len first
8887 int *data_header = (int* )pFaceResult;
8888 data_header[0] = CAMERA_META_DATA_FD;
8889 data_header[1] = (int)data_len;
8890
8891 if(data_len <= 0){
8892 //if face is not valid or do not have face, return
8893 qcamera_callback_argm_t cbArg;
8894 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8895 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
8896 cbArg.msg_type = CAMERA_MSG_META_DATA;
8897 cbArg.data = faceResultBuffer;
8898 cbArg.user_data = faceResultBuffer;
8899 cbArg.cookie = this;
8900 cbArg.release_cb = releaseCameraMemory;
8901 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
8902 if (rc != NO_ERROR) {
8903 LOGE("fail sending notification");
8904 faceResultBuffer->release(faceResultBuffer);
8905 }
8906 return rc;
8907 }
8908 #endif
8909 faceData = pFaceResult + 2 *sizeof(int); //skip two int length
8910 }
8911
8912 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
8913 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
8914
8915 roiData->number_of_faces = detect_data->num_faces_detected;
8916 roiData->faces = faces;
8917 if (roiData->number_of_faces > 0) {
8918 for (int i = 0; i < roiData->number_of_faces; i++) {
8919 faces[i].id = detect_data->faces[i].face_id;
8920 faces[i].score = detect_data->faces[i].score;
8921
8922 // left
8923 faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
8924 detect_data->faces[i].face_boundary.left,
8925 display_dim.width, 2000, -1000);
8926
8927 // top
8928 faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
8929 detect_data->faces[i].face_boundary.top,
8930 display_dim.height, 2000, -1000);
8931
8932 // right
8933 faces[i].rect[2] = faces[i].rect[0] +
8934 MAP_TO_DRIVER_COORDINATE(
8935 detect_data->faces[i].face_boundary.width,
8936 display_dim.width, 2000, 0);
8937
8938 // bottom
8939 faces[i].rect[3] = faces[i].rect[1] +
8940 MAP_TO_DRIVER_COORDINATE(
8941 detect_data->faces[i].face_boundary.height,
8942 display_dim.height, 2000, 0);
8943
8944 if (faces_data->landmark_valid) {
8945 // Center of left eye
8946 if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) {
8947 faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
8948 faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
8949 display_dim.width, 2000, -1000);
8950 faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
8951 faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
8952 display_dim.height, 2000, -1000);
8953 } else {
8954 faces[i].left_eye[0] = FACE_INVALID_POINT;
8955 faces[i].left_eye[1] = FACE_INVALID_POINT;
8956 }
8957
8958 // Center of right eye
8959 if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) {
8960 faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
8961 faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
8962 display_dim.width, 2000, -1000);
8963 faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
8964 faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
8965 display_dim.height, 2000, -1000);
8966 } else {
8967 faces[i].right_eye[0] = FACE_INVALID_POINT;
8968 faces[i].right_eye[1] = FACE_INVALID_POINT;
8969 }
8970
8971 // Center of mouth
8972 if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) {
8973 faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
8974 faces_data->landmark_data.face_landmarks[i].mouth_center.x,
8975 display_dim.width, 2000, -1000);
8976 faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
8977 faces_data->landmark_data.face_landmarks[i].mouth_center.y,
8978 display_dim.height, 2000, -1000);
8979 } else {
8980 faces[i].mouth[0] = FACE_INVALID_POINT;
8981 faces[i].mouth[1] = FACE_INVALID_POINT;
8982 }
8983 } else {
8984 // return -2000 if invalid
8985 faces[i].left_eye[0] = FACE_INVALID_POINT;
8986 faces[i].left_eye[1] = FACE_INVALID_POINT;
8987
8988 faces[i].right_eye[0] = FACE_INVALID_POINT;
8989 faces[i].right_eye[1] = FACE_INVALID_POINT;
8990
8991 faces[i].mouth[0] = FACE_INVALID_POINT;
8992 faces[i].mouth[1] = FACE_INVALID_POINT;
8993 }
8994
8995 #ifndef VANILLA_HAL
8996 #ifdef TARGET_TS_MAKEUP
8997 mFaceRect.left = detect_data->faces[i].face_boundary.left;
8998 mFaceRect.top = detect_data->faces[i].face_boundary.top;
8999 mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
9000 mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
9001 #endif
9002 if (faces_data->smile_valid) {
9003 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
9004 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
9005 }
9006 if (faces_data->blink_valid) {
9007 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
9008 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
9009 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
9010 }
9011 if (faces_data->recog_valid) {
9012 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
9013 }
9014 if (faces_data->gaze_valid) {
9015 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
9016 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
9017 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
9018 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
9019 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
9020 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
9021 }
9022 #endif
9023
9024 }
9025 }
9026 else{
9027 #ifdef TARGET_TS_MAKEUP
9028 memset(&mFaceRect,-1,sizeof(mFaceRect));
9029 #endif
9030 }
9031 qcamera_callback_argm_t cbArg;
9032 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9033 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9034 if(fd_type == QCAMERA_FD_PREVIEW){
9035 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
9036 }
9037 #ifndef VANILLA_HAL
9038 else if(fd_type == QCAMERA_FD_SNAPSHOT){
9039 cbArg.msg_type = CAMERA_MSG_META_DATA;
9040 }
9041 #endif
9042 cbArg.data = faceResultBuffer;
9043 cbArg.metadata = roiData;
9044 cbArg.user_data = faceResultBuffer;
9045 cbArg.cookie = this;
9046 cbArg.release_cb = releaseCameraMemory;
9047 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9048 if (rc != NO_ERROR) {
9049 LOGE("fail sending notification");
9050 faceResultBuffer->release(faceResultBuffer);
9051 }
9052
9053 return rc;
9054 }
9055
9056 /*===========================================================================
9057 * FUNCTION : releaseCameraMemory
9058 *
9059 * DESCRIPTION: releases camera memory objects
9060 *
9061 * PARAMETERS :
9062 * @data : buffer to be released
9063 * @cookie : context data
9064 * @cbStatus: callback status
9065 *
9066 * RETURN : None
9067 *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)9068 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
9069 void */*cookie*/,
9070 int32_t /*cbStatus*/)
9071 {
9072 camera_memory_t *mem = ( camera_memory_t * ) data;
9073 if ( NULL != mem ) {
9074 mem->release(mem);
9075 }
9076 }
9077
9078 /*===========================================================================
9079 * FUNCTION : returnStreamBuffer
9080 *
9081 * DESCRIPTION: returns back a stream buffer
9082 *
9083 * PARAMETERS :
9084 * @data : buffer to be released
9085 * @cookie : context data
9086 * @cbStatus: callback status
9087 *
9088 * RETURN : None
9089 *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)9090 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
9091 void *cookie,
9092 int32_t /*cbStatus*/)
9093 {
9094 QCameraStream *stream = ( QCameraStream * ) cookie;
9095 int idx = *((int *)data);
9096 if ((NULL != stream) && (0 <= idx)) {
9097 stream->bufDone((uint32_t)idx);
9098 } else {
9099 LOGE("Cannot return buffer %d %p", idx, cookie);
9100 }
9101 }
9102
9103 /*===========================================================================
9104 * FUNCTION : processHistogramStats
9105 *
9106 * DESCRIPTION: process histogram stats
9107 *
9108 * PARAMETERS :
9109 * @hist_data : ptr to histogram stats struct
9110 *
9111 * RETURN : int32_t type of status
9112 * NO_ERROR -- success
9113 * none-zero failure code
9114 *==========================================================================*/
processHistogramStats(__unused cam_hist_stats_t & stats_data)9115 int32_t QCamera2HardwareInterface::processHistogramStats(
9116 __unused cam_hist_stats_t &stats_data)
9117 {
9118 #ifndef VANILLA_HAL
9119 if (!mParameters.isHistogramEnabled()) {
9120 LOGH("Histogram not enabled, no ops here");
9121 return NO_ERROR;
9122 }
9123
9124 camera_memory_t *histBuffer = mGetMemory(-1,
9125 sizeof(cam_histogram_data_t),
9126 1,
9127 mCallbackCookie);
9128 if ( NULL == histBuffer ) {
9129 LOGE("Not enough memory for histogram data");
9130 return NO_MEMORY;
9131 }
9132
9133 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
9134 if (pHistData == NULL) {
9135 LOGE("memory data ptr is NULL");
9136 return UNKNOWN_ERROR;
9137 }
9138
9139 switch (stats_data.type) {
9140 case CAM_HISTOGRAM_TYPE_BAYER:
9141 switch (stats_data.bayer_stats.data_type) {
9142 case CAM_STATS_CHANNEL_Y:
9143 case CAM_STATS_CHANNEL_R:
9144 *pHistData = stats_data.bayer_stats.r_stats;
9145 break;
9146 case CAM_STATS_CHANNEL_GR:
9147 *pHistData = stats_data.bayer_stats.gr_stats;
9148 break;
9149 case CAM_STATS_CHANNEL_GB:
9150 case CAM_STATS_CHANNEL_ALL:
9151 *pHistData = stats_data.bayer_stats.gb_stats;
9152 break;
9153 case CAM_STATS_CHANNEL_B:
9154 *pHistData = stats_data.bayer_stats.b_stats;
9155 break;
9156 default:
9157 *pHistData = stats_data.bayer_stats.r_stats;
9158 break;
9159 }
9160 break;
9161 case CAM_HISTOGRAM_TYPE_YUV:
9162 *pHistData = stats_data.yuv_stats;
9163 break;
9164 }
9165
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_STATS_DATA;
9170 cbArg.data = histBuffer;
9171 cbArg.user_data = histBuffer;
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 histBuffer->release(histBuffer);
9178 }
9179 #endif
9180 return NO_ERROR;
9181 }
9182
9183 /*===========================================================================
9184 * FUNCTION : calcThermalLevel
9185 *
9186 * DESCRIPTION: Calculates the target fps range depending on
9187 * the thermal level.
9188 * Note that this function can be called from QCameraParametersIntf
9189 * while mutex is held. So it should not call back into
9190 * QCameraParametersIntf causing deadlock.
9191 *
9192 * PARAMETERS :
9193 * @level : received thermal level
9194 * @minFPS : minimum configured fps range
9195 * @maxFPS : maximum configured fps range
9196 * @minVideoFps: minimum configured fps range
9197 * @maxVideoFps: maximum configured fps range
9198 * @adjustedRange : target fps range
9199 * @skipPattern : target skip pattern
9200 * @bRecordingHint : recording hint value
9201 *
9202 * RETURN : int32_t type of status
9203 * NO_ERROR -- success
9204 * none-zero failure code
9205 *==========================================================================*/
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)9206 int QCamera2HardwareInterface::calcThermalLevel(
9207 qcamera_thermal_level_enum_t level,
9208 const int minFPSi,
9209 const int maxFPSi,
9210 const float &minVideoFps,
9211 const float &maxVideoFps,
9212 cam_fps_range_t &adjustedRange,
9213 enum msm_vfe_frame_skip_pattern &skipPattern,
9214 bool bRecordingHint)
9215 {
9216 const float minFPS = (float)minFPSi;
9217 const float maxFPS = (float)maxFPSi;
9218
9219 LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
9220 "video minfps %f, video maxfpS %f",
9221 level, minFPS, maxFPS, minVideoFps, maxVideoFps);
9222
9223 switch(level) {
9224 case QCAMERA_THERMAL_NO_ADJUSTMENT:
9225 {
9226 adjustedRange.min_fps = minFPS / 1000.0f;
9227 adjustedRange.max_fps = maxFPS / 1000.0f;
9228 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9229 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9230 skipPattern = NO_SKIP;
9231 }
9232 break;
9233 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
9234 {
9235 adjustedRange.min_fps = minFPS / 1000.0f;
9236 adjustedRange.max_fps = maxFPS / 1000.0f;
9237 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
9238 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
9239 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9240 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9241 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
9242 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
9243 if ( adjustedRange.min_fps < 1 ) {
9244 adjustedRange.min_fps = 1;
9245 }
9246 if ( adjustedRange.max_fps < 1 ) {
9247 adjustedRange.max_fps = 1;
9248 }
9249 if ( adjustedRange.video_min_fps < 1 ) {
9250 adjustedRange.video_min_fps = 1;
9251 }
9252 if ( adjustedRange.video_max_fps < 1 ) {
9253 adjustedRange.video_max_fps = 1;
9254 }
9255 skipPattern = EVERY_2FRAME;
9256 }
9257 break;
9258 case QCAMERA_THERMAL_BIG_ADJUSTMENT:
9259 {
9260 adjustedRange.min_fps = minFPS / 1000.0f;
9261 adjustedRange.max_fps = maxFPS / 1000.0f;
9262 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
9263 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
9264 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9265 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9266 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
9267 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
9268 if ( adjustedRange.min_fps < 1 ) {
9269 adjustedRange.min_fps = 1;
9270 }
9271 if ( adjustedRange.max_fps < 1 ) {
9272 adjustedRange.max_fps = 1;
9273 }
9274 if ( adjustedRange.video_min_fps < 1 ) {
9275 adjustedRange.video_min_fps = 1;
9276 }
9277 if ( adjustedRange.video_max_fps < 1 ) {
9278 adjustedRange.video_max_fps = 1;
9279 }
9280 skipPattern = EVERY_4FRAME;
9281 }
9282 break;
9283 case QCAMERA_THERMAL_MAX_ADJUSTMENT:
9284 {
9285 // Stop Preview?
9286 // Set lowest min FPS for now
9287 adjustedRange.min_fps = minFPS/1000.0f;
9288 adjustedRange.max_fps = minFPS/1000.0f;
9289 cam_capability_t *capability = gCamCapability[mCameraId];
9290 for (size_t i = 0;
9291 i < capability->fps_ranges_tbl_cnt;
9292 i++) {
9293 if (capability->fps_ranges_tbl[i].min_fps <
9294 adjustedRange.min_fps) {
9295 adjustedRange.min_fps =
9296 capability->fps_ranges_tbl[i].min_fps;
9297 adjustedRange.max_fps = adjustedRange.min_fps;
9298 }
9299 }
9300 skipPattern = MAX_SKIP;
9301 adjustedRange.video_min_fps = adjustedRange.min_fps;
9302 adjustedRange.video_max_fps = adjustedRange.max_fps;
9303 }
9304 break;
9305 case QCAMERA_THERMAL_SHUTDOWN:
9306 {
9307 // send error notify
9308 LOGE("Received shutdown thermal level. Closing camera");
9309 sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
9310 }
9311 break;
9312 default:
9313 {
9314 LOGW("Invalid thermal level %d", level);
9315 return BAD_VALUE;
9316 }
9317 break;
9318 }
9319 if (level >= QCAMERA_THERMAL_NO_ADJUSTMENT && level <= QCAMERA_THERMAL_MAX_ADJUSTMENT) {
9320 if (bRecordingHint) {
9321 adjustedRange.min_fps = minFPS / 1000.0f;
9322 adjustedRange.max_fps = maxFPS / 1000.0f;
9323 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9324 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9325 skipPattern = NO_SKIP;
9326 LOGH("No FPS mitigation in camcorder mode");
9327 }
9328 LOGH("Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
9329 level, adjustedRange.min_fps, adjustedRange.max_fps,
9330 adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
9331 }
9332
9333 return NO_ERROR;
9334 }
9335
9336 /*===========================================================================
9337 * FUNCTION : recalcFPSRange
9338 *
9339 * DESCRIPTION: adjust the configured fps range regarding
9340 * the last thermal level.
9341 *
9342 * PARAMETERS :
9343 * @minFPS : minimum configured fps range
9344 * @maxFPS : maximum configured fps range
9345 * @minVideoFPS : minimum configured video fps
9346 * @maxVideoFPS : maximum configured video fps
9347 * @adjustedRange : target fps range
9348 * @bRecordingHint : recording hint value
9349 *
9350 * RETURN : int32_t type of status
9351 * NO_ERROR -- success
9352 * none-zero failure code
9353 *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,const float & minVideoFPS,const float & maxVideoFPS,cam_fps_range_t & adjustedRange,bool bRecordingHint)9354 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
9355 const float &minVideoFPS, const float &maxVideoFPS,
9356 cam_fps_range_t &adjustedRange, bool bRecordingHint)
9357 {
9358 enum msm_vfe_frame_skip_pattern skipPattern;
9359 calcThermalLevel(mThermalLevel,
9360 minFPS,
9361 maxFPS,
9362 minVideoFPS,
9363 maxVideoFPS,
9364 adjustedRange,
9365 skipPattern,
9366 bRecordingHint);
9367 return NO_ERROR;
9368 }
9369
9370 /*===========================================================================
9371 * FUNCTION : updateThermalLevel
9372 *
9373 * DESCRIPTION: update thermal level depending on thermal events
9374 *
9375 * PARAMETERS :
9376 * @level : thermal level
9377 *
9378 * RETURN : int32_t type of status
9379 * NO_ERROR -- success
9380 * none-zero failure code
9381 *==========================================================================*/
updateThermalLevel(void * thermal_level)9382 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
9383 {
9384 int ret = NO_ERROR;
9385 cam_fps_range_t adjustedRange;
9386 int minFPS, maxFPS;
9387 float minVideoFPS, maxVideoFPS;
9388 enum msm_vfe_frame_skip_pattern skipPattern;
9389 bool value;
9390 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
9391
9392
9393 if (!mCameraOpened) {
9394 LOGH("Camera is not opened, no need to update camera parameters");
9395 return NO_ERROR;
9396 }
9397
9398 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
9399 qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
9400 if (mParameters.isHfrMode()) {
9401 cam_fps_range_t hfrFpsRange;
9402 mParameters.getHfrFps(hfrFpsRange);
9403 minVideoFPS = hfrFpsRange.video_min_fps;
9404 maxVideoFPS = hfrFpsRange.video_max_fps;
9405 } else {
9406 minVideoFPS = minFPS;
9407 maxVideoFPS = maxFPS;
9408 }
9409
9410 value = mParameters.getRecordingHintValue();
9411 calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
9412 adjustedRange, skipPattern, value );
9413 mThermalLevel = level;
9414
9415 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
9416 ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
9417 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
9418 ret = mParameters.setFrameSkip(skipPattern);
9419 else
9420 LOGW("Incorrect thermal mode %d", thermalMode);
9421
9422 return ret;
9423
9424 }
9425
9426 /*===========================================================================
9427 * FUNCTION : updateParameters
9428 *
9429 * DESCRIPTION: update parameters
9430 *
9431 * PARAMETERS :
9432 * @parms : input parameters string
9433 * @needRestart : output, flag to indicate if preview restart is needed
9434 *
9435 * RETURN : int32_t type of status
9436 * NO_ERROR -- success
9437 * none-zero failure code
9438 *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)9439 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
9440 {
9441 int rc = NO_ERROR;
9442
9443 String8 str = String8(parms);
9444 rc = mParameters.updateParameters(str, needRestart);
9445 setNeedRestart(needRestart);
9446
9447 // update stream based parameter settings
9448 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
9449 if (m_channels[i] != NULL) {
9450 m_channels[i]->UpdateStreamBasedParameters(mParameters);
9451 }
9452 }
9453
9454 return rc;
9455 }
9456
9457 /*===========================================================================
9458 * FUNCTION : commitParameterChanges
9459 *
9460 * DESCRIPTION: commit parameter changes to the backend to take effect
9461 *
9462 * PARAMETERS : none
9463 *
9464 * RETURN : int32_t type of status
9465 * NO_ERROR -- success
9466 * none-zero failure code
9467 * NOTE : This function must be called after updateParameters.
9468 * Otherwise, no change will be passed to backend to take effect.
9469 *==========================================================================*/
commitParameterChanges()9470 int QCamera2HardwareInterface::commitParameterChanges()
9471 {
9472 int rc = NO_ERROR;
9473 rc = mParameters.commitParameters();
9474 if (rc == NO_ERROR) {
9475 // update number of snapshot based on committed parameters setting
9476 rc = mParameters.setNumOfSnapshot();
9477 }
9478 return rc;
9479 }
9480
9481 /*===========================================================================
9482 * FUNCTION : needDebugFps
9483 *
9484 * DESCRIPTION: if fps log info need to be printed out
9485 *
9486 * PARAMETERS : none
9487 *
9488 * RETURN : true: need print out fps log
9489 * false: no need to print out fps log
9490 *==========================================================================*/
needDebugFps()9491 bool QCamera2HardwareInterface::needDebugFps()
9492 {
9493 bool needFps = false;
9494 needFps = mParameters.isFpsDebugEnabled();
9495 return needFps;
9496 }
9497
9498 /*===========================================================================
9499 * FUNCTION : isCACEnabled
9500 *
9501 * DESCRIPTION: if CAC is enabled
9502 *
9503 * PARAMETERS : none
9504 *
9505 * RETURN : true: needed
9506 * false: no need
9507 *==========================================================================*/
isCACEnabled()9508 bool QCamera2HardwareInterface::isCACEnabled()
9509 {
9510 char prop[PROPERTY_VALUE_MAX];
9511 memset(prop, 0, sizeof(prop));
9512 property_get("persist.camera.feature.cac", prop, "0");
9513 int enableCAC = atoi(prop);
9514 return enableCAC == 1;
9515 }
9516
9517 /*===========================================================================
9518 * FUNCTION : is4k2kResolution
9519 *
9520 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
9521 *
9522 * PARAMETERS : none
9523 *
9524 * RETURN : true: needed
9525 * false: no need
9526 *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)9527 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
9528 {
9529 bool enabled = false;
9530 if ((resolution->width == 4096 && resolution->height == 2160) ||
9531 (resolution->width == 3840 && resolution->height == 2160) ) {
9532 enabled = true;
9533 }
9534 return enabled;
9535 }
9536
9537 /*===========================================================================
9538 * FUNCTION : isPreviewRestartEnabled
9539 *
9540 * DESCRIPTION: Check whether preview should be restarted automatically
9541 * during image capture.
9542 *
9543 * PARAMETERS : none
9544 *
9545 * RETURN : true: needed
9546 * false: no need
9547 *==========================================================================*/
isPreviewRestartEnabled()9548 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
9549 {
9550 char prop[PROPERTY_VALUE_MAX];
9551 memset(prop, 0, sizeof(prop));
9552 property_get("persist.camera.feature.restart", prop, "0");
9553 int earlyRestart = atoi(prop);
9554 return earlyRestart == 1;
9555 }
9556
9557 /*===========================================================================
9558 * FUNCTION : needReprocess
9559 *
9560 * DESCRIPTION: if reprocess is needed
9561 *
9562 * PARAMETERS : none
9563 *
9564 * RETURN : true: needed
9565 * false: no need
9566 *==========================================================================*/
needReprocess()9567 bool QCamera2HardwareInterface::needReprocess()
9568 {
9569 bool needReprocess = false;
9570
9571 if (!mParameters.isJpegPictureFormat() &&
9572 !mParameters.isNV21PictureFormat()) {
9573 // RAW image, no need to reprocess
9574 return false;
9575 }
9576
9577 //Disable reprocess for 4K liveshot case but enable if lowpower mode
9578 if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9579 && !isLowPowerMode()) {
9580 return false;
9581 }
9582
9583 // pp feature config
9584 cam_pp_feature_config_t pp_config;
9585 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
9586
9587 //Decide whether to do reprocess or not based on
9588 //ppconfig obtained in the first pass.
9589 getPPConfig(pp_config);
9590
9591 if (pp_config.feature_mask > 0) {
9592 needReprocess = true;
9593 }
9594
9595 LOGH("needReprocess %s", needReprocess ? "true" : "false");
9596 return needReprocess;
9597 }
9598
9599
9600 /*===========================================================================
9601 * FUNCTION : needRotationReprocess
9602 *
9603 * DESCRIPTION: if rotation needs to be done by reprocess in pp
9604 *
9605 * PARAMETERS : none
9606 *
9607 * RETURN : true: needed
9608 * false: no need
9609 *==========================================================================*/
needRotationReprocess()9610 bool QCamera2HardwareInterface::needRotationReprocess()
9611 {
9612 if (!mParameters.isJpegPictureFormat() &&
9613 !mParameters.isNV21PictureFormat()) {
9614 // RAW image, no need to reprocess
9615 return false;
9616 }
9617
9618 //Disable reprocess for 4K liveshot case
9619 if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9620 && !isLowPowerMode()) {
9621 //Disable reprocess for 4K liveshot case
9622 return false;
9623 }
9624
9625 if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
9626 CAM_QCOM_FEATURE_ROTATION) > 0 &&
9627 (mParameters.getJpegRotation() > 0)) {
9628 // current rotation is not zero, and pp has the capability to process rotation
9629 LOGH("need to do reprocess for rotation=%d",
9630 mParameters.getJpegRotation());
9631 return true;
9632 }
9633
9634 return false;
9635 }
9636
9637 /*===========================================================================
9638 * FUNCTION : getThumbnailSize
9639 *
9640 * DESCRIPTION: get user set thumbnail size
9641 *
9642 * PARAMETERS :
9643 * @dim : output of thumbnail dimension
9644 *
9645 * RETURN : none
9646 *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)9647 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
9648 {
9649 mParameters.getThumbnailSize(&dim.width, &dim.height);
9650 }
9651
9652 /*===========================================================================
9653 * FUNCTION : getJpegQuality
9654 *
9655 * DESCRIPTION: get user set jpeg quality
9656 *
9657 * PARAMETERS : none
9658 *
9659 * RETURN : jpeg quality setting
9660 *==========================================================================*/
getJpegQuality()9661 uint32_t QCamera2HardwareInterface::getJpegQuality()
9662 {
9663 uint32_t quality = 0;
9664 quality = mParameters.getJpegQuality();
9665 return quality;
9666 }
9667
9668 /*===========================================================================
9669 * FUNCTION : getExifData
9670 *
9671 * DESCRIPTION: get exif data to be passed into jpeg encoding
9672 *
9673 * PARAMETERS : none
9674 *
9675 * RETURN : exif data from user setting and GPS
9676 *==========================================================================*/
getExifData()9677 QCameraExif *QCamera2HardwareInterface::getExifData()
9678 {
9679 QCameraExif *exif = new QCameraExif();
9680 if (exif == NULL) {
9681 LOGE("No memory for QCameraExif");
9682 return NULL;
9683 }
9684
9685 int32_t rc = NO_ERROR;
9686
9687 // add exif entries
9688 String8 dateTime, subSecTime;
9689 rc = mParameters.getExifDateTime(dateTime, subSecTime);
9690 if(rc == NO_ERROR) {
9691 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
9692 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
9693 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
9694 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
9695 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
9696 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
9697 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
9698 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
9699 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
9700 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
9701 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
9702 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
9703 } else {
9704 LOGW("getExifDateTime failed");
9705 }
9706
9707 rat_t focalLength;
9708 rc = mParameters.getExifFocalLength(&focalLength);
9709 if (rc == NO_ERROR) {
9710 exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
9711 EXIF_RATIONAL,
9712 1,
9713 (void *)&(focalLength));
9714 } else {
9715 LOGW("getExifFocalLength failed");
9716 }
9717
9718 uint16_t isoSpeed = mParameters.getExifIsoSpeed();
9719 if (getSensorType() != CAM_SENSOR_YUV) {
9720 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
9721 EXIF_SHORT,
9722 1,
9723 (void *)&(isoSpeed));
9724 }
9725
9726 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
9727 uint32_t count = 0;
9728
9729 /*gps data might not be available */
9730 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
9731 if(rc == NO_ERROR) {
9732 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
9733 EXIF_ASCII,
9734 count,
9735 (void *)gpsProcessingMethod);
9736 } else {
9737 LOGW("getExifGpsProcessingMethod failed");
9738 }
9739
9740 rat_t latitude[3];
9741 char latRef[2];
9742 rc = mParameters.getExifLatitude(latitude, latRef);
9743 if(rc == NO_ERROR) {
9744 exif->addEntry(EXIFTAGID_GPS_LATITUDE,
9745 EXIF_RATIONAL,
9746 3,
9747 (void *)latitude);
9748 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
9749 EXIF_ASCII,
9750 2,
9751 (void *)latRef);
9752 } else {
9753 LOGW("getExifLatitude failed");
9754 }
9755
9756 rat_t longitude[3];
9757 char lonRef[2];
9758 rc = mParameters.getExifLongitude(longitude, lonRef);
9759 if(rc == NO_ERROR) {
9760 exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
9761 EXIF_RATIONAL,
9762 3,
9763 (void *)longitude);
9764
9765 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
9766 EXIF_ASCII,
9767 2,
9768 (void *)lonRef);
9769 } else {
9770 LOGW("getExifLongitude failed");
9771 }
9772
9773 rat_t altitude;
9774 char altRef;
9775 rc = mParameters.getExifAltitude(&altitude, &altRef);
9776 if(rc == NO_ERROR) {
9777 exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
9778 EXIF_RATIONAL,
9779 1,
9780 (void *)&(altitude));
9781
9782 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
9783 EXIF_BYTE,
9784 1,
9785 (void *)&altRef);
9786 } else {
9787 LOGW("getExifAltitude failed");
9788 }
9789
9790 char gpsDateStamp[20];
9791 rat_t gpsTimeStamp[3];
9792 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
9793 if(rc == NO_ERROR) {
9794 exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
9795 EXIF_ASCII,
9796 (uint32_t)(strlen(gpsDateStamp) + 1),
9797 (void *)gpsDateStamp);
9798
9799 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
9800 EXIF_RATIONAL,
9801 3,
9802 (void *)gpsTimeStamp);
9803 } else {
9804 LOGW("getExifGpsDataTimeStamp failed");
9805 }
9806
9807 #ifdef ENABLE_MODEL_INFO_EXIF
9808
9809 char value[PROPERTY_VALUE_MAX];
9810 if (property_get("persist.sys.exif.make", value, "") > 0 ||
9811 property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
9812 exif->addEntry(EXIFTAGID_MAKE,
9813 EXIF_ASCII, strlen(value) + 1, (void *)value);
9814 } else {
9815 LOGW("getExifMaker failed");
9816 }
9817
9818 if (property_get("persist.sys.exif.model", value, "") > 0 ||
9819 property_get("ro.product.model", value, "QCAM-AA") > 0) {
9820 exif->addEntry(EXIFTAGID_MODEL,
9821 EXIF_ASCII, strlen(value) + 1, (void *)value);
9822 } else {
9823 LOGW("getExifModel failed");
9824 }
9825
9826 if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
9827 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
9828 (uint32_t)(strlen(value) + 1), (void *)value);
9829 } else {
9830 LOGW("getExifSoftware failed");
9831 }
9832
9833 #endif
9834
9835 if (mParameters.useJpegExifRotation()) {
9836 int16_t orientation;
9837 switch (mParameters.getJpegExifRotation()) {
9838 case 0:
9839 orientation = 1;
9840 break;
9841 case 90:
9842 orientation = 6;
9843 break;
9844 case 180:
9845 orientation = 3;
9846 break;
9847 case 270:
9848 orientation = 8;
9849 break;
9850 default:
9851 orientation = 1;
9852 break;
9853 }
9854 exif->addEntry(EXIFTAGID_ORIENTATION,
9855 EXIF_SHORT,
9856 1,
9857 (void *)&orientation);
9858 exif->addEntry(EXIFTAGID_TN_ORIENTATION,
9859 EXIF_SHORT,
9860 1,
9861 (void *)&orientation);
9862 }
9863
9864 return exif;
9865 }
9866
9867 /*===========================================================================
9868 * FUNCTION : setHistogram
9869 *
9870 * DESCRIPTION: set if histogram should be enabled
9871 *
9872 * PARAMETERS :
9873 * @histogram_en : bool flag if histogram should be enabled
9874 *
9875 * RETURN : int32_t type of status
9876 * NO_ERROR -- success
9877 * none-zero failure code
9878 *==========================================================================*/
setHistogram(bool histogram_en)9879 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
9880 {
9881 return mParameters.setHistogram(histogram_en);
9882 }
9883
9884 /*===========================================================================
9885 * FUNCTION : setFaceDetection
9886 *
9887 * DESCRIPTION: set if face detection should be enabled
9888 *
9889 * PARAMETERS :
9890 * @enabled : bool flag if face detection should be enabled
9891 *
9892 * RETURN : int32_t type of status
9893 * NO_ERROR -- success
9894 * none-zero failure code
9895 *==========================================================================*/
setFaceDetection(bool enabled)9896 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
9897 {
9898 return mParameters.setFaceDetection(enabled, true);
9899 }
9900
9901 /*===========================================================================
9902 * FUNCTION : isCaptureShutterEnabled
9903 *
9904 * DESCRIPTION: Check whether shutter should be triggered immediately after
9905 * capture
9906 *
9907 * PARAMETERS :
9908 *
9909 * RETURN : true - regular capture
9910 * false - other type of capture
9911 *==========================================================================*/
isCaptureShutterEnabled()9912 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
9913 {
9914 char prop[PROPERTY_VALUE_MAX];
9915 memset(prop, 0, sizeof(prop));
9916 property_get("persist.camera.feature.shutter", prop, "0");
9917 int enableShutter = atoi(prop);
9918 return enableShutter == 1;
9919 }
9920
9921 /*===========================================================================
9922 * FUNCTION : needProcessPreviewFrame
9923 *
9924 * DESCRIPTION: returns whether preview frame need to be displayed
9925 *
9926 * PARAMETERS :
9927 * @frameID : frameID of frame to be processed
9928 *
9929 * RETURN : int32_t type of status
9930 * NO_ERROR -- success
9931 * none-zero failure code
9932 *==========================================================================*/
needProcessPreviewFrame(uint32_t frameID)9933 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
9934 {
9935 return (((m_stateMachine.isPreviewRunning()) &&
9936 (!isDisplayFrameToSkip(frameID)) &&
9937 (!mParameters.isInstantAECEnabled())) ||
9938 (isPreviewRestartEnabled()));
9939 }
9940
9941 /*===========================================================================
9942 * FUNCTION : needSendPreviewCallback
9943 *
9944 * DESCRIPTION: returns whether preview frame need to callback to APP
9945 *
9946 * PARAMETERS :
9947 *
9948 * RETURN : true - need preview frame callbck
9949 * false - not send preview frame callback
9950 *==========================================================================*/
needSendPreviewCallback()9951 bool QCamera2HardwareInterface::needSendPreviewCallback()
9952 {
9953 return m_stateMachine.isPreviewRunning()
9954 && (mDataCb != NULL)
9955 && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
9956 && m_stateMachine.isPreviewCallbackNeeded();
9957 };
9958
9959 /*===========================================================================
9960 * FUNCTION : setDisplaySkip
9961 *
9962 * DESCRIPTION: set range of frames to skip for preview
9963 *
9964 * PARAMETERS :
9965 * @enabled : TRUE to start skipping frame to display
9966 FALSE to stop skipping frame to display
9967 * @skipCnt : Number of frame to skip. 0 by default
9968 *
9969 * RETURN : None
9970 *==========================================================================*/
setDisplaySkip(bool enabled,uint8_t skipCnt)9971 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
9972 {
9973 pthread_mutex_lock(&mGrallocLock);
9974 if (enabled) {
9975 setDisplayFrameSkip();
9976 setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
9977 } else {
9978 setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
9979 }
9980 pthread_mutex_unlock(&mGrallocLock);
9981 }
9982
9983 /*===========================================================================
9984 * FUNCTION : setDisplayFrameSkip
9985 *
9986 * DESCRIPTION: set range of frames to skip for preview
9987 *
9988 * PARAMETERS :
9989 * @start : frameId to start skip
9990 * @end : frameId to stop skip
9991 *
9992 * RETURN : None
9993 *==========================================================================*/
setDisplayFrameSkip(uint32_t start,uint32_t end)9994 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
9995 uint32_t end)
9996 {
9997 if (start == 0) {
9998 mFrameSkipStart = 0;
9999 mFrameSkipEnd = 0;
10000 return;
10001 }
10002 if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
10003 mFrameSkipStart = start;
10004 }
10005 if ((end == 0) || (end > mFrameSkipEnd)) {
10006 mFrameSkipEnd = end;
10007 }
10008 }
10009
10010 /*===========================================================================
10011 * FUNCTION : isDisplayFrameToSkip
10012 *
10013 * DESCRIPTION: function to determin if input frame falls under skip range
10014 *
10015 * PARAMETERS :
10016 * @frameId : frameId to verify
10017 *
10018 * RETURN : true : need to skip
10019 * false: no need to skip
10020 *==========================================================================*/
isDisplayFrameToSkip(uint32_t frameId)10021 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
10022 {
10023 return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
10024 (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
10025 }
10026
10027 /*===========================================================================
10028 * FUNCTION : prepareHardwareForSnapshot
10029 *
10030 * DESCRIPTION: prepare hardware for snapshot, such as LED
10031 *
10032 * PARAMETERS :
10033 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation
10034 *
10035 * RETURN : int32_t type of status
10036 * NO_ERROR -- success
10037 * none-zero failure code
10038 *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)10039 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
10040 {
10041 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_HW_FOR_SNAPSHOT);
10042 LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
10043 return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
10044 afNeeded);
10045 }
10046
10047 /*===========================================================================
10048 * FUNCTION : needFDMetadata
10049 *
10050 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
10051 *
10052 * PARAMETERS :
10053 * @channel_type: channel type
10054 *
10055 * RETURN : true: needed
10056 * false: no need
10057 *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)10058 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
10059 {
10060 //Note: Currently we only process ZSL channel
10061 bool value = false;
10062 if(channel_type == QCAMERA_CH_TYPE_ZSL){
10063 //check if FD requirement is enabled
10064 if(mParameters.isSnapshotFDNeeded() &&
10065 mParameters.isFaceDetectionEnabled()){
10066 value = true;
10067 LOGH("Face Detection metadata is required in ZSL mode.");
10068 }
10069 }
10070
10071 return value;
10072 }
10073
10074 /*===========================================================================
10075 * FUNCTION : deferredWorkRoutine
10076 *
10077 * DESCRIPTION: data process routine that executes deferred tasks
10078 *
10079 * PARAMETERS :
10080 * @data : user data ptr (QCamera2HardwareInterface)
10081 *
10082 * RETURN : None
10083 *==========================================================================*/
deferredWorkRoutine(void * obj)10084 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
10085 {
10086 int running = 1;
10087 int ret;
10088 uint8_t is_active = FALSE;
10089 int32_t job_status = 0;
10090
10091 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
10092 QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
10093 cmdThread->setName("CAM_defrdWrk");
10094
10095 do {
10096 do {
10097 ret = cam_sem_wait(&cmdThread->cmd_sem);
10098 if (ret != 0 && errno != EINVAL) {
10099 LOGE("cam_sem_wait error (%s)",
10100 strerror(errno));
10101 return NULL;
10102 }
10103 } while (ret != 0);
10104
10105 // we got notified about new cmd avail in cmd queue
10106 camera_cmd_type_t cmd = cmdThread->getCmd();
10107 LOGD("cmd: %d", cmd);
10108 switch (cmd) {
10109 case CAMERA_CMD_TYPE_START_DATA_PROC:
10110 LOGH("start data proc");
10111 is_active = TRUE;
10112 break;
10113 case CAMERA_CMD_TYPE_STOP_DATA_PROC:
10114 LOGH("stop data proc");
10115 is_active = FALSE;
10116 // signal cmd is completed
10117 cam_sem_post(&cmdThread->sync_sem);
10118 break;
10119 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
10120 {
10121 DefWork *dw =
10122 reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
10123
10124 if ( NULL == dw ) {
10125 LOGE("Invalid deferred work");
10126 break;
10127 }
10128
10129 switch( dw->cmd ) {
10130 case CMD_DEF_ALLOCATE_BUFF:
10131 {
10132 QCameraChannel * pChannel = dw->args.allocArgs.ch;
10133
10134 if ( NULL == pChannel ) {
10135 LOGE("Invalid deferred work channel");
10136 job_status = BAD_VALUE;
10137 break;
10138 }
10139
10140 cam_stream_type_t streamType = dw->args.allocArgs.type;
10141 LOGH("Deferred buffer allocation started for stream type: %d",
10142 streamType);
10143
10144 uint32_t iNumOfStreams = pChannel->getNumOfStreams();
10145 QCameraStream *pStream = NULL;
10146 for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
10147 pStream = pChannel->getStreamByIndex(i);
10148
10149 if ( NULL == pStream ) {
10150 job_status = BAD_VALUE;
10151 break;
10152 }
10153
10154 if ( pStream->isTypeOf(streamType)) {
10155 if ( pStream->allocateBuffers() ) {
10156 LOGE("Error allocating buffers !!!");
10157 job_status = NO_MEMORY;
10158 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10159 CAMERA_ERROR_UNKNOWN, 0);
10160 }
10161 break;
10162 }
10163 }
10164 }
10165 break;
10166 case CMD_DEF_PPROC_START:
10167 {
10168 int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
10169 if (ret != NO_ERROR) {
10170 job_status = ret;
10171 LOGE("PPROC Start failed");
10172 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10173 CAMERA_ERROR_UNKNOWN, 0);
10174 break;
10175 }
10176 QCameraChannel * pChannel = dw->args.pprocArgs;
10177 assert(pChannel);
10178
10179 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
10180 LOGE("cannot start postprocessor");
10181 job_status = BAD_VALUE;
10182 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10183 CAMERA_ERROR_UNKNOWN, 0);
10184 }
10185 }
10186 break;
10187 case CMD_DEF_METADATA_ALLOC:
10188 {
10189 int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
10190 if (ret != NO_ERROR) {
10191 job_status = ret;
10192 LOGE("Metadata alloc failed");
10193 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10194 CAMERA_ERROR_UNKNOWN, 0);
10195 break;
10196 }
10197 pme->mMetadataMem = new QCameraMetadataStreamMemory(
10198 QCAMERA_ION_USE_CACHE);
10199
10200 if (pme->mMetadataMem == NULL) {
10201 LOGE("Unable to allocate metadata buffers");
10202 job_status = BAD_VALUE;
10203 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10204 CAMERA_ERROR_UNKNOWN, 0);
10205 } else {
10206 int32_t rc = pme->mMetadataMem->allocate(
10207 dw->args.metadataAllocArgs.bufferCnt,
10208 dw->args.metadataAllocArgs.size,
10209 NON_SECURE);
10210 if (rc < 0) {
10211 delete pme->mMetadataMem;
10212 pme->mMetadataMem = NULL;
10213 }
10214 }
10215 }
10216 break;
10217 case CMD_DEF_CREATE_JPEG_SESSION:
10218 {
10219 QCameraChannel * pChannel = dw->args.pprocArgs;
10220 assert(pChannel);
10221
10222 int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
10223 if (ret != NO_ERROR) {
10224 job_status = ret;
10225 LOGE("Jpeg create failed");
10226 break;
10227 }
10228
10229 if (pme->m_postprocessor.createJpegSession(pChannel)
10230 != NO_ERROR) {
10231 LOGE("cannot create JPEG session");
10232 job_status = UNKNOWN_ERROR;
10233 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10234 CAMERA_ERROR_UNKNOWN, 0);
10235 }
10236 }
10237 break;
10238 case CMD_DEF_PPROC_INIT:
10239 {
10240 int32_t rc = NO_ERROR;
10241
10242 jpeg_encode_callback_t jpegEvtHandle =
10243 dw->args.pprocInitArgs.jpeg_cb;
10244 void* user_data = dw->args.pprocInitArgs.user_data;
10245 QCameraPostProcessor *postProcessor =
10246 &(pme->m_postprocessor);
10247 uint32_t cameraId = pme->mCameraId;
10248 cam_capability_t *capability =
10249 gCamCapability[cameraId];
10250 cam_padding_info_t padding_info;
10251 cam_padding_info_t& cam_capability_padding_info =
10252 capability->padding_info;
10253
10254 if(!pme->mJpegClientHandle) {
10255 rc = pme->initJpegHandle();
10256 if (rc != NO_ERROR) {
10257 LOGE("Error!! creating JPEG handle failed");
10258 job_status = UNKNOWN_ERROR;
10259 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10260 CAMERA_ERROR_UNKNOWN, 0);
10261 break;
10262 }
10263 }
10264 LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
10265
10266 rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
10267 &pme->mJpegMpoHandle,
10268 pme->mJpegClientHandle);
10269 if (rc != 0) {
10270 LOGE("Error!! set JPEG handle failed");
10271 job_status = UNKNOWN_ERROR;
10272 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10273 CAMERA_ERROR_UNKNOWN, 0);
10274 break;
10275 }
10276
10277 /* get max pic size for jpeg work buf calculation*/
10278 rc = postProcessor->init(jpegEvtHandle, user_data);
10279
10280 if (rc != NO_ERROR) {
10281 LOGE("cannot init postprocessor");
10282 job_status = UNKNOWN_ERROR;
10283 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10284 CAMERA_ERROR_UNKNOWN, 0);
10285 break;
10286 }
10287
10288 // update padding info from jpeg
10289 postProcessor->getJpegPaddingReq(padding_info);
10290 if (cam_capability_padding_info.width_padding <
10291 padding_info.width_padding) {
10292 cam_capability_padding_info.width_padding =
10293 padding_info.width_padding;
10294 }
10295 if (cam_capability_padding_info.height_padding <
10296 padding_info.height_padding) {
10297 cam_capability_padding_info.height_padding =
10298 padding_info.height_padding;
10299 }
10300 if (cam_capability_padding_info.plane_padding !=
10301 padding_info.plane_padding) {
10302 cam_capability_padding_info.plane_padding =
10303 mm_stream_calc_lcm(
10304 cam_capability_padding_info.plane_padding,
10305 padding_info.plane_padding);
10306 }
10307 if (cam_capability_padding_info.offset_info.offset_x
10308 != padding_info.offset_info.offset_x) {
10309 cam_capability_padding_info.offset_info.offset_x =
10310 mm_stream_calc_lcm (
10311 cam_capability_padding_info.offset_info.offset_x,
10312 padding_info.offset_info.offset_x);
10313 }
10314 if (cam_capability_padding_info.offset_info.offset_y
10315 != padding_info.offset_info.offset_y) {
10316 cam_capability_padding_info.offset_info.offset_y =
10317 mm_stream_calc_lcm (
10318 cam_capability_padding_info.offset_info.offset_y,
10319 padding_info.offset_info.offset_y);
10320 }
10321 }
10322 break;
10323 case CMD_DEF_PARAM_ALLOC:
10324 {
10325 int32_t rc = NO_ERROR;
10326 if (pme->isDualCamera()) {
10327 rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
10328 } else {
10329 rc = pme->mParameters.allocate();
10330 }
10331 // notify routine would not be initialized by this time.
10332 // So, just update error job status
10333 if (rc != NO_ERROR) {
10334 job_status = rc;
10335 LOGE("Param allocation failed");
10336 break;
10337 }
10338 }
10339 break;
10340 case CMD_DEF_PARAM_INIT:
10341 {
10342 int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
10343 if (rc != NO_ERROR) {
10344 job_status = rc;
10345 LOGE("Param init failed");
10346 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10347 CAMERA_ERROR_UNKNOWN, 0);
10348 break;
10349 }
10350
10351 uint32_t camId = pme->mCameraId;
10352 cam_capability_t * cap = gCamCapability[camId];
10353
10354 if (pme->mCameraHandle == NULL) {
10355 LOGE("Camera handle is null");
10356 job_status = BAD_VALUE;
10357 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10358 CAMERA_ERROR_UNKNOWN, 0);
10359 break;
10360 }
10361
10362 // Now PostProc need calibration data as initialization
10363 // time for jpeg_open and calibration data is a
10364 // get param for now, so params needs to be initialized
10365 // before postproc init
10366 rc = pme->mParameters.init(cap,
10367 pme->mCameraHandle,
10368 pme, pme->m_pFovControl);
10369 if (rc != 0) {
10370 job_status = UNKNOWN_ERROR;
10371 LOGE("Parameter Initialization failed");
10372 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10373 CAMERA_ERROR_UNKNOWN, 0);
10374 break;
10375 }
10376
10377 // Get related cam calibration only in
10378 // dual camera mode
10379 if (pme->getRelatedCamSyncInfo()->sync_control ==
10380 CAM_SYNC_RELATED_SENSORS_ON) {
10381 rc = pme->mParameters.getRelatedCamCalibration(
10382 &(pme->mJpegMetadata.otp_calibration_data));
10383 LOGD("Dumping Calibration Data Version Id %f rc %d",
10384 pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
10385 rc);
10386 if (rc != 0) {
10387 job_status = UNKNOWN_ERROR;
10388 LOGE("getRelatedCamCalibration failed");
10389 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10390 CAMERA_ERROR_UNKNOWN, 0);
10391 break;
10392 }
10393 pme->m_bRelCamCalibValid = true;
10394 }
10395
10396 pme->mJpegMetadata.sensor_mount_angle =
10397 cap->sensor_mount_angle;
10398 pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
10399
10400 pme->mParameters.setMinPpMask(
10401 cap->qcom_supported_feature_mask);
10402 pme->mExifParams.debug_params =
10403 (mm_jpeg_debug_exif_params_t *)
10404 malloc(sizeof(mm_jpeg_debug_exif_params_t));
10405 if (!pme->mExifParams.debug_params) {
10406 LOGE("Out of Memory. Allocation failed for "
10407 "3A debug exif params");
10408 job_status = NO_MEMORY;
10409 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10410 CAMERA_ERROR_UNKNOWN, 0);
10411 break;
10412 }
10413 memset(pme->mExifParams.debug_params, 0,
10414 sizeof(mm_jpeg_debug_exif_params_t));
10415 }
10416 break;
10417 case CMD_DEF_GENERIC:
10418 {
10419 BackgroundTask *bgTask = dw->args.genericArgs;
10420 job_status = bgTask->bgFunction(bgTask->bgArgs);
10421 }
10422 break;
10423 default:
10424 LOGE("Incorrect command : %d", dw->cmd);
10425 }
10426
10427 pme->dequeueDeferredWork(dw, job_status);
10428 }
10429 break;
10430 case CAMERA_CMD_TYPE_EXIT:
10431 running = 0;
10432 break;
10433 default:
10434 break;
10435 }
10436 } while (running);
10437
10438 return NULL;
10439 }
10440
10441 /*===========================================================================
10442 * FUNCTION : queueDeferredWork
10443 *
10444 * DESCRIPTION: function which queues deferred tasks
10445 *
10446 * PARAMETERS :
10447 * @cmd : deferred task
10448 * @args : deferred task arguments
10449 *
10450 * RETURN : job id of deferred job
10451 * : 0 in case of error
10452 *==========================================================================*/
queueDeferredWork(DeferredWorkCmd cmd,DeferWorkArgs args)10453 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
10454 DeferWorkArgs args)
10455 {
10456 Mutex::Autolock l(mDefLock);
10457 for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
10458 if (mDefOngoingJobs[i].mDefJobId == 0) {
10459 DefWork *dw = new DefWork(cmd, sNextJobId, args);
10460 if (!dw) {
10461 LOGE("out of memory.");
10462 return 0;
10463 }
10464 if (mCmdQueue.enqueue(dw)) {
10465 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
10466 mDefOngoingJobs[i].mDefJobStatus = 0;
10467 if (sNextJobId == 0) { // handle overflow
10468 sNextJobId = 1;
10469 }
10470 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
10471 FALSE,
10472 FALSE);
10473 return mDefOngoingJobs[i].mDefJobId;
10474 } else {
10475 LOGD("Command queue not active! cmd = %d", cmd);
10476 delete dw;
10477 return 0;
10478 }
10479 }
10480 }
10481 return 0;
10482 }
10483
10484 /*===========================================================================
10485 * FUNCTION : initJpegHandle
10486 *
10487 * DESCRIPTION: Opens JPEG client and gets a handle.
10488 * Sends Dual cam calibration info if present
10489 *
10490 * RETURN : int32_t type of status
10491 * NO_ERROR -- success
10492 * none-zero failure code
10493 *==========================================================================*/
initJpegHandle()10494 int32_t QCamera2HardwareInterface::initJpegHandle() {
10495 // Check if JPEG client handle is present
10496 LOGH("E");
10497 if(!mJpegClientHandle) {
10498 mm_dimension max_size = {0, 0};
10499 cam_dimension_t size;
10500
10501 mParameters.getMaxPicSize(size);
10502 max_size.w = size.width;
10503 max_size.h = size.height;
10504
10505 if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
10506 if (m_bRelCamCalibValid) {
10507 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10508 max_size, &mJpegMetadata);
10509 } else {
10510 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10511 max_size, NULL);
10512 }
10513 } else {
10514 mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
10515 }
10516 if (!mJpegClientHandle) {
10517 LOGE("Error !! jpeg_open failed!! ");
10518 return UNKNOWN_ERROR;
10519 }
10520 // Set JPEG initialized as true to signify that this camera
10521 // has initialized the handle
10522 mJpegHandleOwner = true;
10523 }
10524 LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
10525 mJpegHandleOwner, mJpegClientHandle, mCameraId);
10526 return NO_ERROR;
10527 }
10528
10529 /*===========================================================================
10530 * FUNCTION : deinitJpegHandle
10531 *
10532 * DESCRIPTION: Closes JPEG client using handle
10533 *
10534 * RETURN : int32_t type of status
10535 * NO_ERROR -- success
10536 * none-zero failure code
10537 *==========================================================================*/
deinitJpegHandle()10538 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
10539 int32_t rc = NO_ERROR;
10540 LOGH("E");
10541 // Check if JPEG client handle is present and inited by this camera
10542 if(mJpegHandleOwner && mJpegClientHandle) {
10543 rc = mJpegHandle.close(mJpegClientHandle);
10544 if (rc != NO_ERROR) {
10545 LOGE("Error!! Closing mJpegClientHandle: %d failed",
10546 mJpegClientHandle);
10547 }
10548 memset(&mJpegHandle, 0, sizeof(mJpegHandle));
10549 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
10550 mJpegHandleOwner = false;
10551 }
10552 mJpegClientHandle = 0;
10553 LOGH("X rc = %d", rc);
10554 return rc;
10555 }
10556
10557 /*===========================================================================
10558 * FUNCTION : setJpegHandleInfo
10559 *
10560 * DESCRIPTION: sets JPEG client handle info
10561 *
10562 * PARAMETERS:
10563 * @ops : JPEG ops
10564 * @mpo_ops : Jpeg MPO ops
10565 * @pJpegClientHandle : o/p Jpeg Client Handle
10566 *
10567 * RETURN : int32_t type of status
10568 * NO_ERROR -- success
10569 * none-zero failure code
10570 *==========================================================================*/
setJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t pJpegClientHandle)10571 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
10572 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
10573
10574 if (pJpegClientHandle && ops && mpo_ops) {
10575 LOGH("Setting JPEG client handle %d",
10576 pJpegClientHandle);
10577 memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
10578 memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
10579 mJpegClientHandle = pJpegClientHandle;
10580 return NO_ERROR;
10581 }
10582 else {
10583 LOGE("Error!! No Handle found: %d",
10584 pJpegClientHandle);
10585 return BAD_VALUE;
10586 }
10587 }
10588
10589 /*===========================================================================
10590 * FUNCTION : getJpegHandleInfo
10591 *
10592 * DESCRIPTION: gets JPEG client handle info
10593 *
10594 * PARAMETERS:
10595 * @ops : JPEG ops
10596 * @mpo_ops : Jpeg MPO ops
10597 * @pJpegClientHandle : o/p Jpeg Client Handle
10598 *
10599 * RETURN : int32_t type of status
10600 * NO_ERROR -- success
10601 * none-zero failure code
10602 *==========================================================================*/
getJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t * pJpegClientHandle)10603 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
10604 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
10605
10606 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
10607 LOGE("Init PProc Deferred work failed");
10608 return UNKNOWN_ERROR;
10609 }
10610 // Copy JPEG ops if present
10611 if (ops && mpo_ops && pJpegClientHandle) {
10612 memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
10613 memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
10614 *pJpegClientHandle = mJpegClientHandle;
10615 LOGH("Getting JPEG client handle %d",
10616 pJpegClientHandle);
10617 return NO_ERROR;
10618 } else {
10619 return BAD_VALUE;
10620 }
10621 }
10622
10623 /*===========================================================================
10624 * FUNCTION : dequeueDeferredWork
10625 *
10626 * DESCRIPTION: function which dequeues deferred tasks
10627 *
10628 * PARAMETERS :
10629 * @dw : deferred work
10630 * @jobStatus: deferred task job status
10631 *
10632 * RETURN : int32_t type of status
10633 * NO_ERROR -- success
10634 * none-zero failure code
10635 *==========================================================================*/
dequeueDeferredWork(DefWork * dw,int32_t jobStatus)10636 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
10637 {
10638 Mutex::Autolock l(mDefLock);
10639 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10640 if (mDefOngoingJobs[i].mDefJobId == dw->id) {
10641 if (jobStatus != NO_ERROR) {
10642 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
10643 LOGH("updating job status %d for id %d",
10644 jobStatus, dw->id);
10645 } else {
10646 mDefOngoingJobs[i].mDefJobId = 0;
10647 mDefOngoingJobs[i].mDefJobStatus = 0;
10648 }
10649 delete dw;
10650 mDefCond.broadcast();
10651 return NO_ERROR;
10652 }
10653 }
10654
10655 return UNKNOWN_ERROR;
10656 }
10657
10658 /*===========================================================================
10659 * FUNCTION : getDefJobStatus
10660 *
10661 * DESCRIPTION: Gets if a deferred task is success/fail
10662 *
10663 * PARAMETERS :
10664 * @job_id : deferred task id
10665 *
10666 * RETURN : NO_ERROR if the job success, otherwise false
10667 *
10668 * PRECONDITION : mDefLock is held by current thread
10669 *==========================================================================*/
getDefJobStatus(uint32_t & job_id)10670 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
10671 {
10672 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10673 if (mDefOngoingJobs[i].mDefJobId == job_id) {
10674 if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
10675 LOGE("job_id (%d) was failed", job_id);
10676 return mDefOngoingJobs[i].mDefJobStatus;
10677 }
10678 else
10679 return NO_ERROR;
10680 }
10681 }
10682 return NO_ERROR;
10683 }
10684
10685
10686 /*===========================================================================
10687 * FUNCTION : checkDeferredWork
10688 *
10689 * DESCRIPTION: checks if a deferred task is in progress
10690 *
10691 * PARAMETERS :
10692 * @job_id : deferred task id
10693 *
10694 * RETURN : true if the task exists, otherwise false
10695 *
10696 * PRECONDITION : mDefLock is held by current thread
10697 *==========================================================================*/
checkDeferredWork(uint32_t & job_id)10698 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
10699 {
10700 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10701 if (mDefOngoingJobs[i].mDefJobId == job_id) {
10702 return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
10703 }
10704 }
10705 return false;
10706 }
10707
10708 /*===========================================================================
10709 * FUNCTION : waitDeferredWork
10710 *
10711 * DESCRIPTION: waits for a deferred task to finish
10712 *
10713 * PARAMETERS :
10714 * @job_id : deferred task id
10715 *
10716 * RETURN : int32_t type of status
10717 * NO_ERROR -- success
10718 * none-zero failure code
10719 *==========================================================================*/
waitDeferredWork(uint32_t & job_id)10720 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
10721 {
10722 Mutex::Autolock l(mDefLock);
10723
10724 if (job_id == 0) {
10725 LOGD("Invalid job id %d", job_id);
10726 return NO_ERROR;
10727 }
10728
10729 while (checkDeferredWork(job_id) == true ) {
10730 mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
10731 }
10732 return getDefJobStatus(job_id);
10733 }
10734
10735 /*===========================================================================
10736 * FUNCTION : scheduleBackgroundTask
10737 *
10738 * DESCRIPTION: Run a requested task in the deferred thread
10739 *
10740 * PARAMETERS :
10741 * @bgTask : Task to perform in the background
10742 *
10743 * RETURN : job id of deferred job
10744 * : 0 in case of error
10745 *==========================================================================*/
scheduleBackgroundTask(BackgroundTask * bgTask)10746 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
10747 {
10748 DeferWorkArgs args;
10749 memset(&args, 0, sizeof(DeferWorkArgs));
10750 args.genericArgs = bgTask;
10751
10752 return queueDeferredWork(CMD_DEF_GENERIC, args);
10753 }
10754
10755 /*===========================================================================
10756 * FUNCTION : waitForBackgroundTask
10757 *
10758 * DESCRIPTION: Wait for a background task to complete
10759 *
10760 * PARAMETERS :
10761 * @taskId : Task id to wait for
10762 *
10763 * RETURN : int32_t type of status
10764 * NO_ERROR -- success
10765 * none-zero failure code
10766 *==========================================================================*/
waitForBackgroundTask(uint32_t & taskId)10767 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
10768 {
10769 return waitDeferredWork(taskId);
10770 }
10771
10772 /*===========================================================================
10773 * FUNCTION : needDeferedAllocation
10774 *
10775 * DESCRIPTION: Function to decide background task for streams
10776 *
10777 * PARAMETERS :
10778 * @stream_type : stream type
10779 *
10780 * RETURN : true - if background task is needed
10781 * false - if background task is NOT needed
10782 *==========================================================================*/
needDeferred(cam_stream_type_t stream_type)10783 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
10784 {
10785 if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
10786 || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
10787 return FALSE;
10788 }
10789
10790 if ((stream_type == CAM_STREAM_TYPE_RAW)
10791 && (mParameters.getofflineRAW())) {
10792 return FALSE;
10793 }
10794
10795 if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
10796 && (!mParameters.getRecordingHintValue())){
10797 return TRUE;
10798 }
10799
10800 if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
10801 || (stream_type == CAM_STREAM_TYPE_METADATA)
10802 || (stream_type == CAM_STREAM_TYPE_RAW)
10803 || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
10804 return TRUE;
10805 }
10806
10807 if (stream_type == CAM_STREAM_TYPE_VIDEO) {
10808 return FALSE;
10809 }
10810 return FALSE;
10811 }
10812
10813 /*===========================================================================
10814 * FUNCTION : needSyncCB
10815 *
10816 * DESCRIPTION: Decide syncronous callback per stream
10817 *
10818 * PARAMETERS :
10819 * @stream_type: stream type
10820 *
10821 * RETURN : true - if background task is needed
10822 * false - if background task is NOT needed
10823 *==========================================================================*/
needSyncCB(cam_stream_type_t stream_type)10824 bool QCamera2HardwareInterface::needSyncCB(cam_stream_type_t stream_type)
10825 {
10826 #ifdef TARGET_TS_MAKEUP
10827 int whiteLevel, cleanLevel;
10828 if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == TRUE) {
10829 return FALSE;
10830 }
10831 #endif
10832
10833 char value[PROPERTY_VALUE_MAX];
10834 property_get("persist.camera.preview.sync_cb", value, "1");
10835 if ((atoi(value) == 1) && (stream_type == CAM_STREAM_TYPE_PREVIEW)) {
10836 return TRUE;
10837 }
10838 return FALSE;
10839 }
10840
10841 /*===========================================================================
10842 * FUNCTION : isRegularCapture
10843 *
10844 * DESCRIPTION: Check configuration for regular catpure
10845 *
10846 * PARAMETERS :
10847 *
10848 * RETURN : true - regular capture
10849 * false - other type of capture
10850 *==========================================================================*/
isRegularCapture()10851 bool QCamera2HardwareInterface::isRegularCapture()
10852 {
10853 bool ret = false;
10854
10855 if (numOfSnapshotsExpected() == 1 &&
10856 !isLongshotEnabled() &&
10857 !mParameters.isHDREnabled() &&
10858 !mParameters.getRecordingHintValue() &&
10859 !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
10860 ret = true;
10861 }
10862 return ret;
10863 }
10864
10865 /*===========================================================================
10866 * FUNCTION : needOfflineReprocessing
10867 *
10868 * DESCRIPTION: Check for offline reprocessing
10869 *
10870 * PARAMETERS :
10871 *
10872 * RETURN : true - regular capture
10873 * false - other type of capture
10874 *==========================================================================*/
needOfflineReprocessing()10875 bool QCamera2HardwareInterface::needOfflineReprocessing()
10876 {
10877 bool ret = false;
10878 if (isRegularCapture()
10879 || isDualCamera()) {
10880 ret = true;
10881 }
10882 return ret;
10883 }
10884
10885 /*===========================================================================
10886 * FUNCTION : getLogLevel
10887 *
10888 * DESCRIPTION: Reads the log level property into a variable
10889 *
10890 * PARAMETERS :
10891 * None
10892 *
10893 * RETURN :
10894 * None
10895 *==========================================================================*/
getLogLevel()10896 void QCamera2HardwareInterface::getLogLevel()
10897 {
10898 char prop[PROPERTY_VALUE_MAX];
10899
10900 property_get("persist.camera.kpi.debug", prop, "1");
10901 gKpiDebugLevel = atoi(prop);
10902 return;
10903 }
10904
10905 /*===========================================================================
10906 * FUNCTION : getSensorType
10907 *
10908 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
10909 *
10910 * PARAMETERS :
10911 * None
10912 *
10913 * RETURN : Type of sensor - bayer or YUV
10914 *
10915 *==========================================================================*/
getSensorType()10916 cam_sensor_t QCamera2HardwareInterface::getSensorType()
10917 {
10918 return gCamCapability[mCameraId]->sensor_type.sens_type;
10919 }
10920
10921 /*===========================================================================
10922 * FUNCTION : startRAWChannel
10923 *
10924 * DESCRIPTION: start RAW Channel
10925 *
10926 * PARAMETERS :
10927 * @pChannel : Src channel to link this RAW channel.
10928 *
10929 * RETURN : int32_t type of status
10930 * NO_ERROR -- success
10931 * none-zero failure code
10932 *==========================================================================*/
startRAWChannel(QCameraChannel * pMetaChannel)10933 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
10934 {
10935 int32_t rc = NO_ERROR;
10936 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
10937 if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
10938 // Find and try to link a metadata stream from preview channel
10939 QCameraStream *pMetaStream = NULL;
10940
10941 if (pMetaChannel != NULL) {
10942 uint32_t streamNum = pMetaChannel->getNumOfStreams();
10943 QCameraStream *pStream = NULL;
10944 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
10945 pStream = pMetaChannel->getStreamByIndex(i);
10946 if ((NULL != pStream) &&
10947 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
10948 pMetaStream = pStream;
10949 break;
10950 }
10951 }
10952
10953 if (NULL != pMetaStream) {
10954 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
10955 if (NO_ERROR != rc) {
10956 LOGE("Metadata stream link failed %d", rc);
10957 }
10958 }
10959 }
10960 rc = pChannel->start();
10961 }
10962 return rc;
10963 }
10964
10965 /*===========================================================================
10966 * FUNCTION : startRecording
10967 *
10968 * DESCRIPTION: start recording impl
10969 *
10970 * PARAMETERS : none
10971 *
10972 * RETURN : int32_t type of status
10973 * NO_ERROR -- success
10974 * none-zero failure code
10975 *==========================================================================*/
stopRAWChannel()10976 int32_t QCamera2HardwareInterface::stopRAWChannel()
10977 {
10978 int32_t rc = NO_ERROR;
10979 rc = stopChannel(QCAMERA_CH_TYPE_RAW);
10980 return rc;
10981 }
10982
10983 /*===========================================================================
10984 * FUNCTION : isLowPowerMode
10985 *
10986 * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
10987 *
10988 * PARAMETERS :
10989 * None
10990 *
10991 * RETURN : TRUE/FALSE
10992 *
10993 *==========================================================================*/
isLowPowerMode()10994 bool QCamera2HardwareInterface::isLowPowerMode()
10995 {
10996 cam_dimension_t dim;
10997 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
10998
10999 char prop[PROPERTY_VALUE_MAX];
11000 property_get("camera.lowpower.record.enable", prop, "0");
11001 int enable = atoi(prop);
11002
11003 //Enable low power mode if :
11004 //1. Video resolution is 2k (2048x1080) or above and
11005 //2. camera.lowpower.record.enable is set
11006
11007 bool isLowpower = mParameters.getRecordingHintValue() && enable
11008 && ((dim.width * dim.height) >= (2048 * 1080));
11009 return isLowpower;
11010 }
11011
11012 /*===========================================================================
11013 * FUNCTION : getBootToMonoTimeOffset
11014 *
11015 * DESCRIPTION: Calculate offset that is used to convert from
11016 * clock domain of boot to monotonic
11017 *
11018 * PARAMETERS :
11019 * None
11020 *
11021 * RETURN : clock offset between boottime and monotonic time.
11022 *
11023 *==========================================================================*/
getBootToMonoTimeOffset()11024 nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset()
11025 {
11026 // try three times to get the clock offset, choose the one
11027 // with the minimum gap in measurements.
11028 const int tries = 3;
11029 nsecs_t bestGap, measured;
11030 for (int i = 0; i < tries; ++i) {
11031 const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
11032 const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
11033 const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
11034 const nsecs_t gap = tmono2 - tmono;
11035 if (i == 0 || gap < bestGap) {
11036 bestGap = gap;
11037 measured = tbase - ((tmono + tmono2) >> 1);
11038 }
11039 }
11040 return measured;
11041 }
11042
11043 /*===========================================================================
11044 * FUNCTION : fillDualCameraFOVControl
11045 *
11046 * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
11047 *
11048 * PARAMETERS : none
11049 *
11050 * RETURN : none
11051 *==========================================================================*/
fillDualCameraFOVControl()11052 void QCamera2HardwareInterface::fillDualCameraFOVControl()
11053 {
11054 qcamera_sm_internal_evt_payload_t *payload =
11055 (qcamera_sm_internal_evt_payload_t *)
11056 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
11057 if (NULL != payload) {
11058 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
11059 payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
11060 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
11061 if (rc != NO_ERROR) {
11062 LOGE("processEvt Dual camera fill FOV control failed");
11063 free(payload);
11064 payload = NULL;
11065 }
11066 } else {
11067 LOGE("No memory for Dual camera fill FOV control event");
11068 }
11069 }
11070
11071 }; // namespace qcamera
11072