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
66 #define HDR_CONFIDENCE_THRESHOLD 0.4
67
68 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds
69
70 // Very long wait, just to be sure we don't deadlock
71 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
72 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
73 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
74 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
75 #define CAMERA_MAX_PARAM_APPLY_DELAY 3
76
77 namespace qcamera {
78
79 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
80 extern pthread_mutex_t gCamLock;
81 volatile uint32_t gCamHalLogLevel = 1;
82 extern uint8_t gNumCameraSessions;
83 uint32_t QCamera2HardwareInterface::sNextJobId = 1;
84
85 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
86 .set_preview_window = QCamera2HardwareInterface::set_preview_window,
87 .set_callbacks = QCamera2HardwareInterface::set_CallBacks,
88 .enable_msg_type = QCamera2HardwareInterface::enable_msg_type,
89 .disable_msg_type = QCamera2HardwareInterface::disable_msg_type,
90 .msg_type_enabled = QCamera2HardwareInterface::msg_type_enabled,
91
92 .start_preview = QCamera2HardwareInterface::start_preview,
93 .stop_preview = QCamera2HardwareInterface::stop_preview,
94 .preview_enabled = QCamera2HardwareInterface::preview_enabled,
95 .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,
96
97 .start_recording = QCamera2HardwareInterface::start_recording,
98 .stop_recording = QCamera2HardwareInterface::stop_recording,
99 .recording_enabled = QCamera2HardwareInterface::recording_enabled,
100 .release_recording_frame = QCamera2HardwareInterface::release_recording_frame,
101
102 .auto_focus = QCamera2HardwareInterface::auto_focus,
103 .cancel_auto_focus = QCamera2HardwareInterface::cancel_auto_focus,
104
105 .take_picture = QCamera2HardwareInterface::take_picture,
106 .cancel_picture = QCamera2HardwareInterface::cancel_picture,
107
108 .set_parameters = QCamera2HardwareInterface::set_parameters,
109 .get_parameters = QCamera2HardwareInterface::get_parameters,
110 .put_parameters = QCamera2HardwareInterface::put_parameters,
111 .send_command = QCamera2HardwareInterface::send_command,
112
113 .release = QCamera2HardwareInterface::release,
114 .dump = QCamera2HardwareInterface::dump,
115 };
116
117 /*===========================================================================
118 * FUNCTION : set_preview_window
119 *
120 * DESCRIPTION: set preview window.
121 *
122 * PARAMETERS :
123 * @device : ptr to camera device struct
124 * @window : window ops table
125 *
126 * RETURN : int32_t type of status
127 * NO_ERROR -- success
128 * none-zero failure code
129 *==========================================================================*/
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)130 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
131 struct preview_stream_ops *window)
132 {
133 ATRACE_CALL();
134 int rc = NO_ERROR;
135 QCamera2HardwareInterface *hw =
136 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
137 if (!hw) {
138 LOGE("NULL camera device");
139 return BAD_VALUE;
140 }
141 LOGD("E camera id %d window = %p", hw->getCameraId(), window);
142
143 hw->lockAPI();
144 qcamera_api_result_t apiResult;
145 rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
146 if (rc == NO_ERROR) {
147 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
148 rc = apiResult.status;
149 }
150 hw->unlockAPI();
151 LOGD("X camera id %d", hw->getCameraId());
152
153 return rc;
154 }
155
156 /*===========================================================================
157 * FUNCTION : set_CallBacks
158 *
159 * DESCRIPTION: set callbacks for notify and data
160 *
161 * PARAMETERS :
162 * @device : ptr to camera device struct
163 * @notify_cb : notify cb
164 * @data_cb : data cb
165 * @data_cb_timestamp : video data cd with timestamp
166 * @get_memory : ops table for request gralloc memory
167 * @user : user data ptr
168 *
169 * RETURN : none
170 *==========================================================================*/
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)171 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
172 camera_notify_callback notify_cb,
173 camera_data_callback data_cb,
174 camera_data_timestamp_callback data_cb_timestamp,
175 camera_request_memory get_memory,
176 void *user)
177 {
178 ATRACE_CALL();
179 QCamera2HardwareInterface *hw =
180 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
181 if (!hw) {
182 LOGE("NULL camera device");
183 return;
184 }
185 LOGD("E camera id %d", hw->getCameraId());
186
187 qcamera_sm_evt_setcb_payload_t payload;
188 payload.notify_cb = notify_cb;
189 payload.data_cb = data_cb;
190 payload.data_cb_timestamp = data_cb_timestamp;
191 payload.get_memory = get_memory;
192 payload.user = user;
193
194 hw->lockAPI();
195 qcamera_api_result_t apiResult;
196 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
197 if (rc == NO_ERROR) {
198 hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
199 }
200 hw->unlockAPI();
201 LOGD("X camera id %d", hw->getCameraId());
202
203 }
204
205 /*===========================================================================
206 * FUNCTION : enable_msg_type
207 *
208 * DESCRIPTION: enable certain msg type
209 *
210 * PARAMETERS :
211 * @device : ptr to camera device struct
212 * @msg_type : msg type mask
213 *
214 * RETURN : none
215 *==========================================================================*/
enable_msg_type(struct camera_device * device,int32_t msg_type)216 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
217 {
218 ATRACE_CALL();
219 QCamera2HardwareInterface *hw =
220 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
221 if (!hw) {
222 LOGE("NULL camera device");
223 return;
224 }
225 LOGD("E camera id %d", hw->getCameraId());
226
227 hw->lockAPI();
228 qcamera_api_result_t apiResult;
229 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
230 if (rc == NO_ERROR) {
231 hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
232 }
233 hw->unlockAPI();
234 LOGD("X camera id %d", hw->getCameraId());
235
236 }
237
238 /*===========================================================================
239 * FUNCTION : disable_msg_type
240 *
241 * DESCRIPTION: disable certain msg type
242 *
243 * PARAMETERS :
244 * @device : ptr to camera device struct
245 * @msg_type : msg type mask
246 *
247 * RETURN : none
248 *==========================================================================*/
disable_msg_type(struct camera_device * device,int32_t msg_type)249 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
250 {
251 ATRACE_CALL();
252 QCamera2HardwareInterface *hw =
253 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
254 if (!hw) {
255 LOGE("NULL camera device");
256 return;
257 }
258 LOGD("E camera id %d", hw->getCameraId());
259
260 hw->lockAPI();
261 qcamera_api_result_t apiResult;
262 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
263 if (rc == NO_ERROR) {
264 hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
265 }
266 hw->unlockAPI();
267 LOGD("X camera id %d", hw->getCameraId());
268
269 }
270
271 /*===========================================================================
272 * FUNCTION : msg_type_enabled
273 *
274 * DESCRIPTION: if certain msg type is enabled
275 *
276 * PARAMETERS :
277 * @device : ptr to camera device struct
278 * @msg_type : msg type mask
279 *
280 * RETURN : 1 -- enabled
281 * 0 -- not enabled
282 *==========================================================================*/
msg_type_enabled(struct camera_device * device,int32_t msg_type)283 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
284 {
285 ATRACE_CALL();
286 int ret = NO_ERROR;
287 QCamera2HardwareInterface *hw =
288 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
289 if (!hw) {
290 LOGE("NULL camera device");
291 return BAD_VALUE;
292 }
293 LOGD("E camera id %d", hw->getCameraId());
294
295 hw->lockAPI();
296 qcamera_api_result_t apiResult;
297 ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
298 if (ret == NO_ERROR) {
299 hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
300 ret = apiResult.enabled;
301 }
302 hw->unlockAPI();
303 LOGD("X camera id %d", hw->getCameraId());
304
305 return ret;
306 }
307
308 /*===========================================================================
309 * FUNCTION : prepare_preview
310 *
311 * DESCRIPTION: prepare preview
312 *
313 * PARAMETERS :
314 * @device : ptr to camera device struct
315 *
316 * RETURN : int32_t type of status
317 * NO_ERROR -- success
318 * none-zero failure code
319 *==========================================================================*/
prepare_preview(struct camera_device * device)320 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
321 {
322 ATRACE_CALL();
323 int ret = NO_ERROR;
324 QCamera2HardwareInterface *hw =
325 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
326 if (!hw) {
327 LOGE("NULL camera device");
328 return BAD_VALUE;
329 }
330 LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
331 hw->getCameraId());
332 hw->lockAPI();
333 qcamera_api_result_t apiResult;
334 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
335 ret = hw->processAPI(evt, NULL);
336 if (ret == NO_ERROR) {
337 hw->waitAPIResult(evt, &apiResult);
338 ret = apiResult.status;
339 }
340 hw->unlockAPI();
341 LOGH("[KPI Perf]: X");
342 return ret;
343 }
344
345
346 /*===========================================================================
347 * FUNCTION : start_preview
348 *
349 * DESCRIPTION: start preview
350 *
351 * PARAMETERS :
352 * @device : ptr to camera device struct
353 *
354 * RETURN : int32_t type of status
355 * NO_ERROR -- success
356 * none-zero failure code
357 *==========================================================================*/
start_preview(struct camera_device * device)358 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
359 {
360 KPI_ATRACE_CALL();
361 int ret = NO_ERROR;
362 QCamera2HardwareInterface *hw =
363 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
364 if (!hw) {
365 LOGE("NULL camera device");
366 return BAD_VALUE;
367 }
368 LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
369 hw->getCameraId());
370
371 // Release the timed perf lock acquired in openCamera
372 hw->m_perfLock.lock_rel_timed();
373
374 hw->m_perfLock.lock_acq();
375 hw->lockAPI();
376 qcamera_api_result_t apiResult;
377 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
378 if (hw->isNoDisplayMode()) {
379 evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
380 }
381 ret = hw->processAPI(evt, NULL);
382 if (ret == NO_ERROR) {
383 hw->waitAPIResult(evt, &apiResult);
384 ret = apiResult.status;
385 }
386 hw->unlockAPI();
387 hw->m_bPreviewStarted = true;
388 LOGI("[KPI Perf]: X ret = %d", ret);
389 return ret;
390 }
391
392 /*===========================================================================
393 * FUNCTION : stop_preview
394 *
395 * DESCRIPTION: stop preview
396 *
397 * PARAMETERS :
398 * @device : ptr to camera device struct
399 *
400 * RETURN : none
401 *==========================================================================*/
stop_preview(struct camera_device * device)402 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
403 {
404 KPI_ATRACE_CALL();
405 QCamera2HardwareInterface *hw =
406 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
407 if (!hw) {
408 LOGE("NULL camera device");
409 return;
410 }
411 LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
412 hw->getCameraId());
413
414 // Disable power Hint for preview
415 hw->m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
416
417 hw->m_perfLock.lock_acq();
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_CALL();
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_CALL();
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_CALL();
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_CALL();
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_CALL();
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 LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
653 hw->getCameraId());
654 // Give HWI control to call pre_start_recording in single camera mode.
655 // In dual-cam mode, this control belongs to muxer.
656 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
657 ret = pre_start_recording(device);
658 if (ret != NO_ERROR) {
659 LOGE("pre_start_recording failed with ret = %d", ret);
660 return ret;
661 }
662 }
663
664 hw->lockAPI();
665 qcamera_api_result_t apiResult;
666 ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
667 if (ret == NO_ERROR) {
668 hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
669 ret = apiResult.status;
670 }
671 hw->unlockAPI();
672 hw->m_bRecordStarted = true;
673 LOGI("[KPI Perf]: X ret = %d", ret);
674
675 return ret;
676 }
677
678 /*===========================================================================
679 * FUNCTION : stop_recording
680 *
681 * DESCRIPTION: stop recording
682 *
683 * PARAMETERS :
684 * @device : ptr to camera device struct
685 *
686 * RETURN : none
687 *==========================================================================*/
stop_recording(struct camera_device * device)688 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
689 {
690 ATRACE_CALL();
691 QCamera2HardwareInterface *hw =
692 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
693 if (!hw) {
694 LOGE("NULL camera device");
695 return;
696 }
697 LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
698 hw->getCameraId());
699
700 hw->lockAPI();
701 qcamera_api_result_t apiResult;
702 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
703 if (ret == NO_ERROR) {
704 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
705 }
706 hw->unlockAPI();
707 LOGI("[KPI Perf]: X ret = %d", ret);
708 }
709
710 /*===========================================================================
711 * FUNCTION : recording_enabled
712 *
713 * DESCRIPTION: if recording is running
714 *
715 * PARAMETERS :
716 * @device : ptr to camera device struct
717 *
718 * RETURN : 1 -- running
719 * 0 -- not running
720 *==========================================================================*/
recording_enabled(struct camera_device * device)721 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
722 {
723 ATRACE_CALL();
724 int ret = NO_ERROR;
725 QCamera2HardwareInterface *hw =
726 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
727 if (!hw) {
728 LOGE("NULL camera device");
729 return BAD_VALUE;
730 }
731 LOGD("E camera id %d", hw->getCameraId());
732 hw->lockAPI();
733 qcamera_api_result_t apiResult;
734 ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
735 if (ret == NO_ERROR) {
736 hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
737 ret = apiResult.enabled;
738 }
739 hw->unlockAPI();
740 LOGD("X camera id %d", hw->getCameraId());
741
742 return ret;
743 }
744
745 /*===========================================================================
746 * FUNCTION : release_recording_frame
747 *
748 * DESCRIPTION: return recording frame back
749 *
750 * PARAMETERS :
751 * @device : ptr to camera device struct
752 * @opaque : ptr to frame to be returned
753 *
754 * RETURN : none
755 *==========================================================================*/
release_recording_frame(struct camera_device * device,const void * opaque)756 void QCamera2HardwareInterface::release_recording_frame(
757 struct camera_device *device, const void *opaque)
758 {
759 ATRACE_CALL();
760 QCamera2HardwareInterface *hw =
761 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
762 if (!hw) {
763 LOGE("NULL camera device");
764 return;
765 }
766 if (!opaque) {
767 LOGE("Error!! Frame info is NULL");
768 return;
769 }
770 LOGD("E camera id %d", hw->getCameraId());
771 hw->lockAPI();
772 qcamera_api_result_t apiResult;
773 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
774 if (ret == NO_ERROR) {
775 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
776 }
777 hw->unlockAPI();
778 LOGD("X camera id %d", hw->getCameraId());
779 }
780
781 /*===========================================================================
782 * FUNCTION : auto_focus
783 *
784 * DESCRIPTION: start auto focus
785 *
786 * PARAMETERS :
787 * @device : ptr to camera device struct
788 *
789 * RETURN : int32_t type of status
790 * NO_ERROR -- success
791 * none-zero failure code
792 *==========================================================================*/
auto_focus(struct camera_device * device)793 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
794 {
795 KPI_ATRACE_INT("Camera:AutoFocus", 1);
796 int ret = NO_ERROR;
797 QCamera2HardwareInterface *hw =
798 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
799 if (!hw) {
800 LOGE("NULL camera device");
801 return BAD_VALUE;
802 }
803 LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
804 hw->getCameraId());
805 hw->lockAPI();
806 qcamera_api_result_t apiResult;
807 ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
808 if (ret == NO_ERROR) {
809 hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
810 ret = apiResult.status;
811 }
812 hw->unlockAPI();
813 LOGH("[KPI Perf] : X ret = %d", ret);
814
815 return ret;
816 }
817
818 /*===========================================================================
819 * FUNCTION : cancel_auto_focus
820 *
821 * DESCRIPTION: cancel auto focus
822 *
823 * PARAMETERS :
824 * @device : ptr to camera device struct
825 *
826 * RETURN : int32_t type of status
827 * NO_ERROR -- success
828 * none-zero failure code
829 *==========================================================================*/
cancel_auto_focus(struct camera_device * device)830 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
831 {
832 ATRACE_CALL();
833 int ret = NO_ERROR;
834 QCamera2HardwareInterface *hw =
835 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
836 if (!hw) {
837 LOGE("NULL camera device");
838 return BAD_VALUE;
839 }
840 LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
841 hw->getCameraId());
842 hw->lockAPI();
843 qcamera_api_result_t apiResult;
844 ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
845 if (ret == NO_ERROR) {
846 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
847 ret = apiResult.status;
848 }
849 hw->unlockAPI();
850 LOGH("[KPI Perf] : X ret = %d", ret);
851 return ret;
852 }
853
854 /*===========================================================================
855 * FUNCTION : pre_take_picture
856 *
857 * DESCRIPTION: pre take picture, restart preview if necessary.
858 *
859 * PARAMETERS :
860 * @device : ptr to camera device struct
861 *
862 * RETURN : int32_t type of status
863 * NO_ERROR -- success
864 * none-zero failure code
865 *==========================================================================*/
pre_take_picture(struct camera_device * device)866 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
867 {
868 ATRACE_CALL();
869 int ret = NO_ERROR;
870 QCamera2HardwareInterface *hw =
871 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
872 if (!hw) {
873 LOGE("NULL camera device");
874 return BAD_VALUE;
875 }
876 LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
877 hw->getCameraId());
878 hw->lockAPI();
879 qcamera_api_result_t apiResult;
880 ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
881 if (ret == NO_ERROR) {
882 hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
883 ret = apiResult.status;
884 }
885 hw->unlockAPI();
886 LOGH("[KPI Perf]: X");
887 return ret;
888 }
889
890 /*===========================================================================
891 * FUNCTION : take_picture
892 *
893 * DESCRIPTION: take picture
894 *
895 * PARAMETERS :
896 * @device : ptr to camera device struct
897 *
898 * RETURN : int32_t type of status
899 * NO_ERROR -- success
900 * none-zero failure code
901 *==========================================================================*/
take_picture(struct camera_device * device)902 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
903 {
904 KPI_ATRACE_CALL();
905 int ret = NO_ERROR;
906 QCamera2HardwareInterface *hw =
907 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
908 if (!hw) {
909 LOGE("NULL camera device");
910 return BAD_VALUE;
911 }
912 LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
913 hw->getCameraId());
914 if (!hw->mLongshotEnabled) {
915 hw->m_perfLock.lock_acq();
916 }
917 qcamera_api_result_t apiResult;
918
919 /** Added support for Retro-active Frames:
920 * takePicture() is called before preparing Snapshot to indicate the
921 * mm-camera-channel to pick up legacy frames even
922 * before LED estimation is triggered.
923 */
924
925 LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
926 hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
927 hw->isLongshotEnabled());
928
929 // Check for Retro-active Frames
930 if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
931 !hw->isLiveSnapshot() && hw->isZSLMode() &&
932 !hw->isHDRMode() && !hw->isLongshotEnabled()) {
933 // Set Retro Picture Mode
934 hw->setRetroPicture(1);
935 hw->m_bLedAfAecLock = 0;
936 LOGL("Retro Enabled");
937
938 // Give HWI control to call pre_take_picture in single camera mode.
939 // In dual-cam mode, this control belongs to muxer.
940 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
941 ret = pre_take_picture(device);
942 if (ret != NO_ERROR) {
943 LOGE("pre_take_picture failed with ret = %d",ret);
944 return ret;
945 }
946 }
947
948 /* Call take Picture for total number of snapshots required.
949 This includes the number of retro frames and normal frames */
950 hw->lockAPI();
951 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
952 if (ret == NO_ERROR) {
953 // Wait for retro frames, before calling prepare snapshot
954 LOGD("Wait for Retro frames to be done");
955 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
956 ret = apiResult.status;
957 }
958 /* Unlock API since it is acquired in prepare snapshot seperately */
959 hw->unlockAPI();
960
961 /* Prepare snapshot in case LED needs to be flashed */
962 LOGD("Start Prepare Snapshot");
963 ret = hw->prepare_snapshot(device);
964 }
965 else {
966 hw->setRetroPicture(0);
967 // Check if prepare snapshot is done
968 if (!hw->mPrepSnapRun) {
969 // Ignore the status from prepare_snapshot
970 hw->prepare_snapshot(device);
971 }
972
973 // Give HWI control to call pre_take_picture in single camera mode.
974 // In dual-cam mode, this control belongs to muxer.
975 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
976 ret = pre_take_picture(device);
977 if (ret != NO_ERROR) {
978 LOGE("pre_take_picture failed with ret = %d",ret);
979 return ret;
980 }
981 }
982
983 // Regardless what the result value for prepare_snapshot,
984 // go ahead with capture anyway. Just like the way autofocus
985 // is handled in capture case
986 /* capture */
987 LOGL("Capturing normal frames");
988 hw->lockAPI();
989 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
990 if (ret == NO_ERROR) {
991 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
992 ret = apiResult.status;
993 }
994 hw->unlockAPI();
995 if (!hw->isLongshotEnabled()){
996 // For longshot mode, we prepare snapshot only once
997 hw->mPrepSnapRun = false;
998 }
999 }
1000 LOGI("[KPI Perf]: X ret = %d", ret);
1001 return ret;
1002 }
1003
1004 /*===========================================================================
1005 * FUNCTION : cancel_picture
1006 *
1007 * DESCRIPTION: cancel current take picture request
1008 *
1009 * PARAMETERS :
1010 * @device : ptr to camera device struct
1011 *
1012 * RETURN : int32_t type of status
1013 * NO_ERROR -- success
1014 * none-zero failure code
1015 *==========================================================================*/
cancel_picture(struct camera_device * device)1016 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
1017 {
1018 ATRACE_CALL();
1019 int ret = NO_ERROR;
1020 QCamera2HardwareInterface *hw =
1021 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1022 if (!hw) {
1023 LOGE("NULL camera device");
1024 return BAD_VALUE;
1025 }
1026 LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
1027 hw->getCameraId());
1028 hw->lockAPI();
1029 qcamera_api_result_t apiResult;
1030 ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
1031 if (ret == NO_ERROR) {
1032 hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
1033 ret = apiResult.status;
1034 }
1035 hw->unlockAPI();
1036 LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);
1037
1038 return ret;
1039 }
1040
1041 /*===========================================================================
1042 * FUNCTION : set_parameters
1043 *
1044 * DESCRIPTION: set camera parameters
1045 *
1046 * PARAMETERS :
1047 * @device : ptr to camera device struct
1048 * @parms : string of packed parameters
1049 *
1050 * RETURN : int32_t type of status
1051 * NO_ERROR -- success
1052 * none-zero failure code
1053 *==========================================================================*/
set_parameters(struct camera_device * device,const char * parms)1054 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
1055 const char *parms)
1056 {
1057 ATRACE_CALL();
1058 int ret = NO_ERROR;
1059 QCamera2HardwareInterface *hw =
1060 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1061 if (!hw) {
1062 LOGE("NULL camera device");
1063 return BAD_VALUE;
1064 }
1065 LOGD("E camera id %d", hw->getCameraId());
1066 hw->lockAPI();
1067 qcamera_api_result_t apiResult;
1068 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
1069 if (ret == NO_ERROR) {
1070 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
1071 ret = apiResult.status;
1072 }
1073
1074 // Give HWI control to restart (if necessary) after set params
1075 // in single camera mode. In dual-cam mode, this control belongs to muxer.
1076 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
1077 if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1078 LOGD("stopping after param change");
1079 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1080 if (ret == NO_ERROR) {
1081 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1082 ret = apiResult.status;
1083 }
1084 }
1085
1086 if (ret == NO_ERROR) {
1087 LOGD("committing param change");
1088 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1089 if (ret == NO_ERROR) {
1090 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1091 ret = apiResult.status;
1092 }
1093 }
1094
1095 if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1096 LOGD("restarting after param change");
1097 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1098 if (ret == NO_ERROR) {
1099 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1100 ret = apiResult.status;
1101 }
1102 }
1103 }
1104
1105 hw->unlockAPI();
1106 LOGD("X camera id %d ret %d", hw->getCameraId(), ret);
1107
1108 return ret;
1109 }
1110
1111 /*===========================================================================
1112 * FUNCTION : stop_after_set_params
1113 *
1114 * DESCRIPTION: stop after a set param call, if necessary
1115 *
1116 * PARAMETERS :
1117 * @device : ptr to camera device struct
1118 *
1119 * RETURN : int32_t type of status
1120 * NO_ERROR -- success
1121 * none-zero failure code
1122 *==========================================================================*/
stop_after_set_params(struct camera_device * device)1123 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
1124 {
1125 ATRACE_CALL();
1126 int ret = NO_ERROR;
1127 QCamera2HardwareInterface *hw =
1128 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1129 if (!hw) {
1130 LOGE("NULL camera device");
1131 return BAD_VALUE;
1132 }
1133 LOGD("E camera id %d", hw->getCameraId());
1134 hw->lockAPI();
1135 qcamera_api_result_t apiResult;
1136
1137 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1138 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1139 if (ret == NO_ERROR) {
1140 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1141 ret = apiResult.status;
1142 }
1143 } else {
1144 LOGE("is not supposed to be called in single-camera mode");
1145 ret = INVALID_OPERATION;
1146 }
1147
1148 hw->unlockAPI();
1149 LOGD("X camera id %d", hw->getCameraId());
1150
1151 return ret;
1152 }
1153
1154 /*===========================================================================
1155 * FUNCTION : commit_params
1156 *
1157 * DESCRIPTION: commit after a set param call
1158 *
1159 * PARAMETERS :
1160 * @device : ptr to camera device struct
1161 *
1162 * RETURN : int32_t type of status
1163 * NO_ERROR -- success
1164 * none-zero failure code
1165 *==========================================================================*/
commit_params(struct camera_device * device)1166 int QCamera2HardwareInterface::commit_params(struct camera_device *device)
1167 {
1168 ATRACE_CALL();
1169 int ret = NO_ERROR;
1170 QCamera2HardwareInterface *hw =
1171 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1172 if (!hw) {
1173 LOGE("NULL camera device");
1174 return BAD_VALUE;
1175 }
1176 LOGD("E camera id %d", hw->getCameraId());
1177 hw->lockAPI();
1178 qcamera_api_result_t apiResult;
1179
1180 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1181 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1182 if (ret == NO_ERROR) {
1183 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1184 ret = apiResult.status;
1185 }
1186 } else {
1187 LOGE("is not supposed to be called in single-camera mode");
1188 ret = INVALID_OPERATION;
1189 }
1190
1191 hw->unlockAPI();
1192 LOGD("X camera id %d", hw->getCameraId());
1193
1194 return ret;
1195 }
1196
1197 /*===========================================================================
1198 * FUNCTION : restart_after_set_params
1199 *
1200 * DESCRIPTION: restart after a set param call, if necessary
1201 *
1202 * PARAMETERS :
1203 * @device : ptr to camera device struct
1204 *
1205 * RETURN : int32_t type of status
1206 * NO_ERROR -- success
1207 * none-zero failure code
1208 *==========================================================================*/
restart_after_set_params(struct camera_device * device)1209 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
1210 {
1211 ATRACE_CALL();
1212 int ret = NO_ERROR;
1213 QCamera2HardwareInterface *hw =
1214 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1215 if (!hw) {
1216 LOGE("NULL camera device");
1217 return BAD_VALUE;
1218 }
1219 LOGD("E camera id %d", hw->getCameraId());
1220 hw->lockAPI();
1221 qcamera_api_result_t apiResult;
1222
1223 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1224 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1225 if (ret == NO_ERROR) {
1226 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1227 ret = apiResult.status;
1228 }
1229 } else {
1230 LOGE("is not supposed to be called in single-camera mode");
1231 ret = INVALID_OPERATION;
1232 }
1233
1234 hw->unlockAPI();
1235 LOGD("X camera id %d", hw->getCameraId());
1236 return ret;
1237 }
1238
1239 /*===========================================================================
1240 * FUNCTION : get_parameters
1241 *
1242 * DESCRIPTION: query camera parameters
1243 *
1244 * PARAMETERS :
1245 * @device : ptr to camera device struct
1246 *
1247 * RETURN : packed parameters in a string
1248 *==========================================================================*/
get_parameters(struct camera_device * device)1249 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
1250 {
1251 ATRACE_CALL();
1252 char *ret = NULL;
1253 QCamera2HardwareInterface *hw =
1254 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1255 if (!hw) {
1256 LOGE("NULL camera device");
1257 return NULL;
1258 }
1259 LOGD("E camera id %d", hw->getCameraId());
1260 hw->lockAPI();
1261 qcamera_api_result_t apiResult;
1262 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
1263 if (rc == NO_ERROR) {
1264 hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
1265 ret = apiResult.params;
1266 }
1267 hw->unlockAPI();
1268 LOGD("E camera id %d", hw->getCameraId());
1269
1270 return ret;
1271 }
1272
1273 /*===========================================================================
1274 * FUNCTION : put_parameters
1275 *
1276 * DESCRIPTION: return camera parameters string back to HAL
1277 *
1278 * PARAMETERS :
1279 * @device : ptr to camera device struct
1280 * @parm : ptr to parameter string to be returned
1281 *
1282 * RETURN : none
1283 *==========================================================================*/
put_parameters(struct camera_device * device,char * parm)1284 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
1285 char *parm)
1286 {
1287 ATRACE_CALL();
1288 QCamera2HardwareInterface *hw =
1289 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1290 if (!hw) {
1291 LOGE("NULL camera device");
1292 return;
1293 }
1294 LOGD("E camera id %d", hw->getCameraId());
1295 hw->lockAPI();
1296 qcamera_api_result_t apiResult;
1297 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
1298 if (ret == NO_ERROR) {
1299 hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
1300 }
1301 hw->unlockAPI();
1302 LOGD("E camera id %d", hw->getCameraId());
1303 }
1304
1305 /*===========================================================================
1306 * FUNCTION : send_command
1307 *
1308 * DESCRIPTION: command to be executed
1309 *
1310 * PARAMETERS :
1311 * @device : ptr to camera device struct
1312 * @cmd : cmd to be executed
1313 * @arg1 : ptr to optional argument1
1314 * @arg2 : ptr to optional argument2
1315 *
1316 * RETURN : int32_t type of status
1317 * NO_ERROR -- success
1318 * none-zero failure code
1319 *==========================================================================*/
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1320 int QCamera2HardwareInterface::send_command(struct camera_device *device,
1321 int32_t cmd,
1322 int32_t arg1,
1323 int32_t arg2)
1324 {
1325 ATRACE_CALL();
1326 int ret = NO_ERROR;
1327 QCamera2HardwareInterface *hw =
1328 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1329 if (!hw) {
1330 LOGE("NULL camera device");
1331 return BAD_VALUE;
1332 }
1333 LOGD("E camera id %d", hw->getCameraId());
1334
1335 qcamera_sm_evt_command_payload_t payload;
1336 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1337 payload.cmd = cmd;
1338 payload.arg1 = arg1;
1339 payload.arg2 = arg2;
1340 hw->lockAPI();
1341 qcamera_api_result_t apiResult;
1342 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
1343 if (ret == NO_ERROR) {
1344 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
1345 ret = apiResult.status;
1346 }
1347 hw->unlockAPI();
1348 LOGD("E camera id %d", hw->getCameraId());
1349
1350 return ret;
1351 }
1352
1353 /*===========================================================================
1354 * FUNCTION : send_command_restart
1355 *
1356 * DESCRIPTION: restart if necessary after a send_command
1357 *
1358 * PARAMETERS :
1359 * @device : ptr to camera device struct
1360 * @cmd : cmd to be executed
1361 * @arg1 : ptr to optional argument1
1362 * @arg2 : ptr to optional argument2
1363 *
1364 * RETURN : int32_t type of status
1365 * NO_ERROR -- success
1366 * none-zero failure code
1367 *==========================================================================*/
send_command_restart(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1368 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
1369 int32_t cmd,
1370 int32_t arg1,
1371 int32_t arg2)
1372 {
1373 ATRACE_CALL();
1374 int ret = NO_ERROR;
1375 QCamera2HardwareInterface *hw =
1376 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1377 if (!hw) {
1378 LOGE("NULL camera device");
1379 return BAD_VALUE;
1380 }
1381
1382 qcamera_sm_evt_command_payload_t payload;
1383 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1384 payload.cmd = cmd;
1385 payload.arg1 = arg1;
1386 payload.arg2 = arg2;
1387 hw->lockAPI();
1388 qcamera_api_result_t apiResult;
1389 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
1390 if (ret == NO_ERROR) {
1391 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
1392 ret = apiResult.status;
1393 }
1394 hw->unlockAPI();
1395 LOGD("E camera id %d", hw->getCameraId());
1396
1397 return ret;
1398 }
1399
1400 /*===========================================================================
1401 * FUNCTION : release
1402 *
1403 * DESCRIPTION: release camera resource
1404 *
1405 * PARAMETERS :
1406 * @device : ptr to camera device struct
1407 *
1408 * RETURN : none
1409 *==========================================================================*/
release(struct camera_device * device)1410 void QCamera2HardwareInterface::release(struct camera_device *device)
1411 {
1412 ATRACE_CALL();
1413 QCamera2HardwareInterface *hw =
1414 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1415 if (!hw) {
1416 LOGE("NULL camera device");
1417 return;
1418 }
1419 LOGD("E camera id %d", hw->getCameraId());
1420 hw->lockAPI();
1421 qcamera_api_result_t apiResult;
1422 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
1423 if (ret == NO_ERROR) {
1424 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
1425 }
1426 hw->unlockAPI();
1427 LOGD("E camera id %d", hw->getCameraId());
1428 }
1429
1430 /*===========================================================================
1431 * FUNCTION : dump
1432 *
1433 * DESCRIPTION: dump camera status
1434 *
1435 * PARAMETERS :
1436 * @device : ptr to camera device struct
1437 * @fd : fd for status to be dumped to
1438 *
1439 * RETURN : int32_t type of status
1440 * NO_ERROR -- success
1441 * none-zero failure code
1442 *==========================================================================*/
dump(struct camera_device * device,int fd)1443 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
1444 {
1445 int ret = NO_ERROR;
1446
1447 //Log level property is read when "adb shell dumpsys media.camera" is
1448 //called so that the log level can be controlled without restarting
1449 //media server
1450 getLogLevel();
1451 QCamera2HardwareInterface *hw =
1452 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1453 if (!hw) {
1454 LOGE("NULL camera device");
1455 return BAD_VALUE;
1456 }
1457 LOGD("E camera id %d", hw->getCameraId());
1458 hw->lockAPI();
1459 qcamera_api_result_t apiResult;
1460 ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
1461 if (ret == NO_ERROR) {
1462 hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
1463 ret = apiResult.status;
1464 }
1465 hw->unlockAPI();
1466 LOGD("E camera id %d", hw->getCameraId());
1467
1468 return ret;
1469 }
1470
1471 /*===========================================================================
1472 * FUNCTION : close_camera_device
1473 *
1474 * DESCRIPTION: close camera device
1475 *
1476 * PARAMETERS :
1477 * @device : ptr to camera device struct
1478 *
1479 * RETURN : int32_t type of status
1480 * NO_ERROR -- success
1481 * none-zero failure code
1482 *==========================================================================*/
close_camera_device(hw_device_t * hw_dev)1483 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
1484 {
1485 KPI_ATRACE_CALL();
1486 int ret = NO_ERROR;
1487
1488 QCamera2HardwareInterface *hw =
1489 reinterpret_cast<QCamera2HardwareInterface *>(
1490 reinterpret_cast<camera_device_t *>(hw_dev)->priv);
1491 if (!hw) {
1492 LOGE("NULL camera device");
1493 return BAD_VALUE;
1494 }
1495 LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
1496 delete hw;
1497 LOGI("[KPI Perf]: X");
1498 return ret;
1499 }
1500
1501 /*===========================================================================
1502 * FUNCTION : register_face_image
1503 *
1504 * DESCRIPTION: register a face image into imaging lib for face authenticatio/
1505 * face recognition
1506 *
1507 * PARAMETERS :
1508 * @device : ptr to camera device struct
1509 * @img_ptr : ptr to image buffer
1510 * @config : ptr to config about input image, i.e., format, dimension, and etc.
1511 *
1512 * RETURN : >=0 unique ID of face registerd.
1513 * <0 failure.
1514 *==========================================================================*/
register_face_image(struct camera_device * device,void * img_ptr,cam_pp_offline_src_config_t * config)1515 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
1516 void *img_ptr,
1517 cam_pp_offline_src_config_t *config)
1518 {
1519 ATRACE_CALL();
1520 int ret = NO_ERROR;
1521 QCamera2HardwareInterface *hw =
1522 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1523 if (!hw) {
1524 LOGE("NULL camera device");
1525 return BAD_VALUE;
1526 }
1527 LOGD("E camera id %d", hw->getCameraId());
1528 qcamera_sm_evt_reg_face_payload_t payload;
1529 memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
1530 payload.img_ptr = img_ptr;
1531 payload.config = config;
1532 hw->lockAPI();
1533 qcamera_api_result_t apiResult;
1534 ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
1535 if (ret == NO_ERROR) {
1536 hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
1537 ret = apiResult.handle;
1538 }
1539 hw->unlockAPI();
1540 LOGD("E camera id %d", hw->getCameraId());
1541
1542 return ret;
1543 }
1544
1545 /*===========================================================================
1546 * FUNCTION : prepare_snapshot
1547 *
1548 * DESCRIPTION: prepares hardware for snapshot
1549 *
1550 * PARAMETERS :
1551 * @device : ptr to camera device struct
1552 *
1553 * RETURN : int32_t type of status
1554 * NO_ERROR -- success
1555 * none-zero failure code
1556 *==========================================================================*/
prepare_snapshot(struct camera_device * device)1557 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
1558 {
1559 ATRACE_CALL();
1560 int ret = NO_ERROR;
1561 QCamera2HardwareInterface *hw =
1562 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1563 if (!hw) {
1564 LOGE("NULL camera device");
1565 return BAD_VALUE;
1566 }
1567 if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
1568 // For longshot mode, we prepare snapshot only once
1569 LOGH("prepare snapshot only once ");
1570 return NO_ERROR;
1571 }
1572 LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
1573 hw->getCameraId());
1574 hw->lockAPI();
1575 qcamera_api_result_t apiResult;
1576
1577 /* Prepare snapshot in case LED needs to be flashed */
1578 if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
1579 /* Prepare snapshot in case LED needs to be flashed */
1580 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
1581 if (ret == NO_ERROR) {
1582 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
1583 ret = apiResult.status;
1584 }
1585 hw->mPrepSnapRun = true;
1586 }
1587 hw->unlockAPI();
1588 LOGH("[KPI Perf]: X, ret: %d", ret);
1589 return ret;
1590 }
1591
1592 /*===========================================================================
1593 * FUNCTION : QCamera2HardwareInterface
1594 *
1595 * DESCRIPTION: constructor of QCamera2HardwareInterface
1596 *
1597 * PARAMETERS :
1598 * @cameraId : camera ID
1599 *
1600 * RETURN : none
1601 *==========================================================================*/
QCamera2HardwareInterface(uint32_t cameraId)1602 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
1603 : mCameraId(cameraId),
1604 mCameraHandle(NULL),
1605 mCameraOpened(false),
1606 m_bRelCamCalibValid(false),
1607 mPreviewWindow(NULL),
1608 mMsgEnabled(0),
1609 mStoreMetaDataInFrame(0),
1610 mJpegCb(NULL),
1611 mCallbackCookie(NULL),
1612 mJpegCallbackCookie(NULL),
1613 m_bMpoEnabled(TRUE),
1614 m_stateMachine(this),
1615 m_smThreadActive(true),
1616 m_postprocessor(this),
1617 m_thermalAdapter(QCameraThermalAdapter::getInstance()),
1618 m_cbNotifier(this),
1619 m_bPreviewStarted(false),
1620 m_bRecordStarted(false),
1621 m_currentFocusState(CAM_AF_STATE_INACTIVE),
1622 mDumpFrmCnt(0U),
1623 mDumpSkipCnt(0U),
1624 mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
1625 mActiveAF(false),
1626 m_HDRSceneEnabled(false),
1627 mLongshotEnabled(false),
1628 mLiveSnapshotThread(0),
1629 mIntPicThread(0),
1630 mFlashNeeded(false),
1631 mDeviceRotation(0U),
1632 mCaptureRotation(0U),
1633 mJpegExifRotation(0U),
1634 mUseJpegExifRotation(false),
1635 mIs3ALocked(false),
1636 mPrepSnapRun(false),
1637 mZoomLevel(0),
1638 mPreviewRestartNeeded(false),
1639 mVFrameCount(0),
1640 mVLastFrameCount(0),
1641 mVLastFpsTime(0),
1642 mVFps(0),
1643 mPFrameCount(0),
1644 mPLastFrameCount(0),
1645 mPLastFpsTime(0),
1646 mPFps(0),
1647 mInstantAecFrameCount(0),
1648 m_bIntJpegEvtPending(false),
1649 m_bIntRawEvtPending(false),
1650 mReprocJob(0),
1651 mJpegJob(0),
1652 mMetadataAllocJob(0),
1653 mInitPProcJob(0),
1654 mParamAllocJob(0),
1655 mParamInitJob(0),
1656 mOutputCount(0),
1657 mInputCount(0),
1658 mAdvancedCaptureConfigured(false),
1659 mHDRBracketingEnabled(false),
1660 mNumPreviewFaces(-1),
1661 mJpegClientHandle(0),
1662 mJpegHandleOwner(false),
1663 mMetadataMem(NULL),
1664 mCACDoneReceived(false),
1665 m_bNeedRestart(false)
1666 {
1667 #ifdef TARGET_TS_MAKEUP
1668 memset(&mFaceRect, -1, sizeof(mFaceRect));
1669 #endif
1670 getLogLevel();
1671 ATRACE_CALL();
1672 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1673 mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1674 mCameraDevice.common.close = close_camera_device;
1675 mCameraDevice.ops = &mCameraOps;
1676 mCameraDevice.priv = this;
1677
1678 pthread_mutex_init(&m_lock, NULL);
1679 pthread_cond_init(&m_cond, NULL);
1680
1681 m_apiResultList = NULL;
1682
1683 pthread_mutex_init(&m_evtLock, NULL);
1684 pthread_cond_init(&m_evtCond, NULL);
1685 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1686
1687
1688 pthread_mutex_init(&m_int_lock, NULL);
1689 pthread_cond_init(&m_int_cond, NULL);
1690
1691 memset(m_channels, 0, sizeof(m_channels));
1692
1693 memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
1694
1695 memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
1696
1697 memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
1698 memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
1699 memset(&mJpegHandle, 0, sizeof(mJpegHandle));
1700 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
1701
1702 mDeferredWorkThread.launch(deferredWorkRoutine, this);
1703 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1704 m_perfLock.lock_init();
1705
1706 pthread_mutex_init(&mGrallocLock, NULL);
1707 mEnqueuedBuffers = 0;
1708 mFrameSkipStart = 0;
1709 mFrameSkipEnd = 0;
1710 mLastPreviewFrameID = 0;
1711
1712 //Load and read GPU library.
1713 lib_surface_utils = NULL;
1714 LINK_get_surface_pixel_alignment = NULL;
1715 mSurfaceStridePadding = CAM_PAD_TO_32;
1716 lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
1717 if (lib_surface_utils) {
1718 *(void **)&LINK_get_surface_pixel_alignment =
1719 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
1720 if (LINK_get_surface_pixel_alignment) {
1721 mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
1722 }
1723 dlclose(lib_surface_utils);
1724 }
1725 }
1726
1727 /*===========================================================================
1728 * FUNCTION : ~QCamera2HardwareInterface
1729 *
1730 * DESCRIPTION: destructor of QCamera2HardwareInterface
1731 *
1732 * PARAMETERS : none
1733 *
1734 * RETURN : none
1735 *==========================================================================*/
~QCamera2HardwareInterface()1736 QCamera2HardwareInterface::~QCamera2HardwareInterface()
1737 {
1738 LOGH("E");
1739
1740 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1741 mDeferredWorkThread.exit();
1742
1743 if (mMetadataMem != NULL) {
1744 delete mMetadataMem;
1745 mMetadataMem = NULL;
1746 }
1747
1748 m_perfLock.lock_acq();
1749 lockAPI();
1750 m_smThreadActive = false;
1751 unlockAPI();
1752 m_stateMachine.releaseThread();
1753 closeCamera();
1754 m_perfLock.lock_rel();
1755 m_perfLock.lock_deinit();
1756 pthread_mutex_destroy(&m_lock);
1757 pthread_cond_destroy(&m_cond);
1758 pthread_mutex_destroy(&m_evtLock);
1759 pthread_cond_destroy(&m_evtCond);
1760 pthread_mutex_destroy(&m_int_lock);
1761 pthread_cond_destroy(&m_int_cond);
1762 pthread_mutex_destroy(&mGrallocLock);
1763 LOGH("X");
1764 }
1765
1766 /*===========================================================================
1767 * FUNCTION : deferPPInit
1768 *
1769 * DESCRIPTION: Queue postproc init task to deferred thread
1770 *
1771 * PARAMETERS : none
1772 *
1773 * RETURN : uint32_t job id of pproc init job
1774 * 0 -- failure
1775 *==========================================================================*/
deferPPInit()1776 uint32_t QCamera2HardwareInterface::deferPPInit()
1777 {
1778 // init pproc
1779 DeferWorkArgs args;
1780 DeferPProcInitArgs pprocInitArgs;
1781
1782 memset(&args, 0, sizeof(DeferWorkArgs));
1783 memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
1784
1785 pprocInitArgs.jpeg_cb = jpegEvtHandle;
1786 pprocInitArgs.user_data = this;
1787 args.pprocInitArgs = pprocInitArgs;
1788
1789 return queueDeferredWork(CMD_DEF_PPROC_INIT,
1790 args);
1791 }
1792
1793 /*===========================================================================
1794 * FUNCTION : openCamera
1795 *
1796 * DESCRIPTION: open camera
1797 *
1798 * PARAMETERS :
1799 * @hw_device : double ptr for camera device struct
1800 *
1801 * RETURN : int32_t type of status
1802 * NO_ERROR -- success
1803 * none-zero failure code
1804 *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1805 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1806 {
1807 KPI_ATRACE_CALL();
1808 int rc = NO_ERROR;
1809 if (mCameraOpened) {
1810 *hw_device = NULL;
1811 LOGE("Permission Denied");
1812 return PERMISSION_DENIED;
1813 }
1814 LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
1815 mCameraId);
1816 m_perfLock.lock_acq_timed(CAMERA_OPEN_PERF_TIME_OUT);
1817 rc = openCamera();
1818 if (rc == NO_ERROR){
1819 *hw_device = &mCameraDevice.common;
1820 if (m_thermalAdapter.init(this) != 0) {
1821 LOGW("Init thermal adapter failed");
1822 }
1823 }
1824 else
1825 *hw_device = NULL;
1826
1827 LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
1828 mCameraId, rc);
1829
1830 return rc;
1831 }
1832
1833 /*===========================================================================
1834 * FUNCTION : openCamera
1835 *
1836 * DESCRIPTION: open camera
1837 *
1838 * PARAMETERS : none
1839 *
1840 * RETURN : int32_t type of status
1841 * NO_ERROR -- success
1842 * none-zero failure code
1843 *==========================================================================*/
openCamera()1844 int QCamera2HardwareInterface::openCamera()
1845 {
1846 int32_t rc = NO_ERROR;
1847 char value[PROPERTY_VALUE_MAX];
1848
1849 if (mCameraHandle) {
1850 LOGE("Failure: Camera already opened");
1851 return ALREADY_EXISTS;
1852 }
1853
1854 rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
1855 if (rc < 0) {
1856 LOGE("Failed to reserve flash for camera id: %d",
1857 mCameraId);
1858 return UNKNOWN_ERROR;
1859 }
1860
1861 // alloc param buffer
1862 DeferWorkArgs args;
1863 memset(&args, 0, sizeof(args));
1864 mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
1865 if (mParamAllocJob == 0) {
1866 LOGE("Failed queueing PARAM_ALLOC job");
1867 return -ENOMEM;
1868 }
1869
1870 if (gCamCapability[mCameraId] != NULL) {
1871 // allocate metadata buffers
1872 DeferWorkArgs args;
1873 DeferMetadataAllocArgs metadataAllocArgs;
1874
1875 memset(&args, 0, sizeof(args));
1876 memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
1877
1878 uint32_t padding =
1879 gCamCapability[mCameraId]->padding_info.plane_padding;
1880 metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
1881 padding);
1882 metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
1883 args.metadataAllocArgs = metadataAllocArgs;
1884
1885 mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
1886 if (mMetadataAllocJob == 0) {
1887 LOGE("Failed to allocate metadata buffer");
1888 rc = -ENOMEM;
1889 goto error_exit1;
1890 }
1891
1892 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1893 if (rc) {
1894 LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1895 rc, mCameraHandle);
1896 goto error_exit2;
1897 }
1898
1899 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1900 camEvtHandle,
1901 (void *) this);
1902 } else {
1903 LOGH("Capabilities not inited, initializing now.");
1904
1905 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1906 if (rc) {
1907 LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1908 rc, mCameraHandle);
1909 goto error_exit2;
1910 }
1911
1912 if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
1913 LOGE("initCapabilities failed.");
1914 rc = UNKNOWN_ERROR;
1915 goto error_exit3;
1916 }
1917
1918 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1919 camEvtHandle,
1920 (void *) this);
1921 }
1922
1923 // Init params in the background
1924 // 1. It's safe to queue init job, even if alloc job is not yet complete.
1925 // It will be queued to the same thread, so the alloc is guaranteed to
1926 // finish first.
1927 // 2. However, it is not safe to begin param init until after camera is
1928 // open. That is why we wait until after camera open completes to schedule
1929 // this task.
1930 memset(&args, 0, sizeof(args));
1931 mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
1932 if (mParamInitJob == 0) {
1933 LOGE("Failed queuing PARAM_INIT job");
1934 rc = -ENOMEM;
1935 goto error_exit3;
1936 }
1937
1938 mCameraOpened = true;
1939
1940 //Notify display HAL that a camera session is active.
1941 //But avoid calling the same during bootup because camera service might open/close
1942 //cameras at boot time during its initialization and display service will also internally
1943 //wait for camera service to initialize first while calling this display API, resulting in a
1944 //deadlock situation. Since boot time camera open/close calls are made only to fetch
1945 //capabilities, no need of this display bw optimization.
1946 //Use "service.bootanim.exit" property to know boot status.
1947 property_get("service.bootanim.exit", value, "0");
1948 if (atoi(value) == 1) {
1949 pthread_mutex_lock(&gCamLock);
1950 if (gNumCameraSessions++ == 0) {
1951 setCameraLaunchStatus(true);
1952 }
1953 pthread_mutex_unlock(&gCamLock);
1954 }
1955
1956 return NO_ERROR;
1957
1958 error_exit3:
1959 if(mJpegClientHandle) {
1960 deinitJpegHandle();
1961 }
1962 mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1963 mCameraHandle = NULL;
1964 error_exit2:
1965 waitDeferredWork(mMetadataAllocJob);
1966 error_exit1:
1967 waitDeferredWork(mParamAllocJob);
1968 return rc;
1969
1970 }
1971
1972 /*===========================================================================
1973 * FUNCTION : bundleRelatedCameras
1974 *
1975 * DESCRIPTION: bundle cameras to enable syncing of cameras
1976 *
1977 * PARAMETERS :
1978 * @sync :indicates whether syncing is On or Off
1979 * @sessionid :session id for other camera session
1980 *
1981 * RETURN : int32_t type of status
1982 * NO_ERROR -- success
1983 * none-zero failure code
1984 *==========================================================================*/
bundleRelatedCameras(bool syncOn,uint32_t sessionid)1985 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn,
1986 uint32_t sessionid)
1987 {
1988 LOGD("bundleRelatedCameras sync %d with sessionid %d",
1989 syncOn, sessionid);
1990
1991 int32_t rc = mParameters.bundleRelatedCameras(syncOn, sessionid);
1992 if (rc != NO_ERROR) {
1993 LOGE("bundleRelatedCameras failed %d", rc);
1994 return rc;
1995 }
1996 return rc;
1997 }
1998
1999 /*===========================================================================
2000 * FUNCTION : getCameraSessionId
2001 *
2002 * DESCRIPTION: gets the backend session Id of this HWI instance
2003 *
2004 * PARAMETERS :
2005 * @sessionid : pointer to the output session id
2006 *
2007 * RETURN : int32_t type of status
2008 * NO_ERROR -- success
2009 * none-zero failure code
2010 *==========================================================================*/
getCameraSessionId(uint32_t * session_id)2011 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
2012 {
2013 int32_t rc = NO_ERROR;
2014
2015 if(session_id != NULL) {
2016 rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
2017 session_id);
2018 LOGD("Getting Camera Session Id %d", *session_id);
2019 } else {
2020 LOGE("Session Id is Null");
2021 return UNKNOWN_ERROR;
2022 }
2023 return rc;
2024 }
2025
2026 /*===========================================================================
2027 * FUNCTION : getRelatedCamSyncInfo
2028 *
2029 * DESCRIPTION:returns the related cam sync info for this HWI instance
2030 *
2031 * PARAMETERS :none
2032 *
2033 * RETURN : const pointer to cam_sync_related_sensors_event_info_t
2034 *==========================================================================*/
2035 const cam_sync_related_sensors_event_info_t*
getRelatedCamSyncInfo(void)2036 QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
2037 {
2038 return mParameters.getRelatedCamSyncInfo();
2039 }
2040
2041 /*===========================================================================
2042 * FUNCTION : setRelatedCamSyncInfo
2043 *
2044 * DESCRIPTION:sets the related cam sync info for this HWI instance
2045 *
2046 * PARAMETERS :
2047 * @info : ptr to related cam info parameters
2048 *
2049 * RETURN : int32_t type of status
2050 * NO_ERROR -- success
2051 * none-zero failure code
2052 *==========================================================================*/
setRelatedCamSyncInfo(cam_sync_related_sensors_event_info_t * info)2053 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
2054 cam_sync_related_sensors_event_info_t* info)
2055 {
2056 if(info) {
2057 return mParameters.setRelatedCamSyncInfo(info);
2058 } else {
2059 return BAD_TYPE;
2060 }
2061 }
2062
2063 /*===========================================================================
2064 * FUNCTION : getMpoComposition
2065 *
2066 * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
2067 * or not
2068 *
2069 * PARAMETERS :none
2070 *
2071 * RETURN : bool indicates whether mpo composition is enabled or not
2072 *==========================================================================*/
getMpoComposition(void)2073 bool QCamera2HardwareInterface::getMpoComposition(void)
2074 {
2075 LOGH("MpoComposition:%d ", m_bMpoEnabled);
2076 return m_bMpoEnabled;
2077 }
2078
2079 /*===========================================================================
2080 * FUNCTION : setMpoComposition
2081 *
2082 * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
2083 *
2084 * PARAMETERS :
2085 * @enable : indicates whether Mpo composition enabled or not
2086 *
2087 * RETURN : int32_t type of status
2088 * NO_ERROR -- success
2089 * none-zero failure code
2090 *==========================================================================*/
setMpoComposition(bool enable)2091 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
2092 {
2093 // By default set Mpo composition to disable
2094 m_bMpoEnabled = false;
2095
2096 // Enable Mpo composition only if
2097 // 1) frame sync is ON between two cameras and
2098 // 2) any advanced features are not enabled (AOST features) and
2099 // 3) not in recording mode (for liveshot case)
2100 // 4) flash is not needed
2101 if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
2102 !mParameters.isAdvCamFeaturesEnabled() &&
2103 !mParameters.getRecordingHintValue() &&
2104 !mFlashNeeded &&
2105 !isLongshotEnabled()) {
2106 m_bMpoEnabled = enable;
2107 LOGH("MpoComposition:%d ", m_bMpoEnabled);
2108 return NO_ERROR;
2109 } else {
2110 return BAD_TYPE;
2111 }
2112 }
2113
2114 /*===========================================================================
2115 * FUNCTION : getRecordingHintValue
2116 *
2117 * DESCRIPTION:function to retrieve recording hint value
2118 *
2119 * PARAMETERS :none
2120 *
2121 * RETURN : bool indicates whether recording hint is enabled or not
2122 *==========================================================================*/
getRecordingHintValue(void)2123 bool QCamera2HardwareInterface::getRecordingHintValue(void)
2124 {
2125 return mParameters.getRecordingHintValue();
2126 }
2127
2128 /*===========================================================================
2129 * FUNCTION : setRecordingHintValue
2130 *
2131 * DESCRIPTION:set recording hint value
2132 *
2133 * PARAMETERS :
2134 * @enable : video hint value
2135 *
2136 * RETURN : int32_t type of status
2137 * NO_ERROR -- success
2138 * none-zero failure code
2139 *==========================================================================*/
setRecordingHintValue(int32_t value)2140 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
2141 {
2142 return mParameters.updateRecordingHintValue(value);
2143 }
2144
2145 /*===========================================================================
2146 * FUNCTION : closeCamera
2147 *
2148 * DESCRIPTION: close camera
2149 *
2150 * PARAMETERS : none
2151 *
2152 * RETURN : int32_t type of status
2153 * NO_ERROR -- success
2154 * none-zero failure code
2155 *==========================================================================*/
closeCamera()2156 int QCamera2HardwareInterface::closeCamera()
2157 {
2158 int rc = NO_ERROR;
2159 int i;
2160 char value[PROPERTY_VALUE_MAX];
2161 LOGI("E");
2162 if (!mCameraOpened) {
2163 return NO_ERROR;
2164 }
2165 LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
2166 mCameraId);
2167
2168 // set open flag to false
2169 mCameraOpened = false;
2170
2171 // Reset Stream config info
2172 mParameters.setStreamConfigure(false, false, true);
2173
2174 // deinit Parameters
2175 mParameters.deinit();
2176
2177 // exit notifier
2178 m_cbNotifier.exit();
2179
2180 // stop and deinit postprocessor
2181 waitDeferredWork(mReprocJob);
2182 // Close the JPEG session
2183 waitDeferredWork(mJpegJob);
2184 m_postprocessor.stop();
2185 deinitJpegHandle();
2186 m_postprocessor.deinit();
2187 mInitPProcJob = 0; // reset job id, so pproc can be reinited later
2188
2189 m_thermalAdapter.deinit();
2190
2191 // delete all channels if not already deleted
2192 for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2193 if (m_channels[i] != NULL) {
2194 m_channels[i]->stop();
2195 delete m_channels[i];
2196 m_channels[i] = NULL;
2197 }
2198 }
2199
2200 //free all pending api results here
2201 if(m_apiResultList != NULL) {
2202 api_result_list *apiResultList = m_apiResultList;
2203 api_result_list *apiResultListNext;
2204 while (apiResultList != NULL) {
2205 apiResultListNext = apiResultList->next;
2206 free(apiResultList);
2207 apiResultList = apiResultListNext;
2208 }
2209 }
2210
2211 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2212 mCameraHandle = NULL;
2213
2214 //Notify display HAL that there is no active camera session
2215 //but avoid calling the same during bootup. Refer to openCamera
2216 //for more details.
2217 property_get("service.bootanim.exit", value, "0");
2218 if (atoi(value) == 1) {
2219 pthread_mutex_lock(&gCamLock);
2220 if (--gNumCameraSessions == 0) {
2221 setCameraLaunchStatus(false);
2222 }
2223 pthread_mutex_unlock(&gCamLock);
2224 }
2225
2226 if (mExifParams.debug_params) {
2227 free(mExifParams.debug_params);
2228 mExifParams.debug_params = NULL;
2229 }
2230
2231 if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
2232 LOGD("Failed to release flash for camera id: %d",
2233 mCameraId);
2234 }
2235
2236 LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
2237 mCameraId, rc);
2238
2239 return rc;
2240 }
2241
2242 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
2243
2244 /*===========================================================================
2245 * FUNCTION : initCapabilities
2246 *
2247 * DESCRIPTION: initialize camera capabilities in static data struct
2248 *
2249 * PARAMETERS :
2250 * @cameraId : camera Id
2251 *
2252 * RETURN : int32_t type of status
2253 * NO_ERROR -- success
2254 * none-zero failure code
2255 *==========================================================================*/
initCapabilities(uint32_t cameraId,mm_camera_vtbl_t * cameraHandle)2256 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
2257 mm_camera_vtbl_t *cameraHandle)
2258 {
2259 ATRACE_CALL();
2260 int rc = NO_ERROR;
2261 QCameraHeapMemory *capabilityHeap = NULL;
2262
2263 /* Allocate memory for capability buffer */
2264 capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
2265 rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
2266 if(rc != OK) {
2267 LOGE("No memory for cappability");
2268 goto allocate_failed;
2269 }
2270
2271 /* Map memory for capability buffer */
2272 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
2273
2274 cam_buf_map_type_list bufMapList;
2275 rc = QCameraBufferMaps::makeSingletonBufMapList(
2276 CAM_MAPPING_BUF_TYPE_CAPABILITY,
2277 0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
2278 0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
2279 bufMapList);
2280
2281 if (rc == NO_ERROR) {
2282 rc = cameraHandle->ops->map_bufs(cameraHandle->camera_handle,
2283 &bufMapList);
2284 }
2285
2286 if(rc < 0) {
2287 LOGE("failed to map capability buffer");
2288 goto map_failed;
2289 }
2290
2291 /* Query Capability */
2292 rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
2293 if(rc < 0) {
2294 LOGE("failed to query capability");
2295 goto query_failed;
2296 }
2297 gCamCapability[cameraId] =
2298 (cam_capability_t *)malloc(sizeof(cam_capability_t));
2299
2300 if (!gCamCapability[cameraId]) {
2301 LOGE("out of memory");
2302 goto query_failed;
2303 }
2304 memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),
2305 sizeof(cam_capability_t));
2306 gCamCapability[cameraId]->analysis_padding_info.offset_info.offset_x = 0;
2307 gCamCapability[cameraId]->analysis_padding_info.offset_info.offset_y = 0;
2308
2309 rc = NO_ERROR;
2310
2311 query_failed:
2312 cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
2313 CAM_MAPPING_BUF_TYPE_CAPABILITY);
2314 map_failed:
2315 capabilityHeap->deallocate();
2316 delete capabilityHeap;
2317 allocate_failed:
2318 return rc;
2319 }
2320
2321 /*===========================================================================
2322 * FUNCTION : getCapabilities
2323 *
2324 * DESCRIPTION: query camera capabilities
2325 *
2326 * PARAMETERS :
2327 * @cameraId : camera Id
2328 * @info : camera info struct to be filled in with camera capabilities
2329 *
2330 * RETURN : int type of status
2331 * NO_ERROR -- success
2332 * none-zero failure code
2333 *==========================================================================*/
getCapabilities(uint32_t cameraId,struct camera_info * info,cam_sync_type_t * p_cam_type)2334 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
2335 struct camera_info *info, cam_sync_type_t *p_cam_type)
2336 {
2337 ATRACE_CALL();
2338 int rc = NO_ERROR;
2339 struct camera_info *p_info = NULL;
2340 pthread_mutex_lock(&gCamLock);
2341 p_info = get_cam_info(cameraId, p_cam_type);
2342 p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
2343 p_info->static_camera_characteristics = NULL;
2344 memcpy(info, p_info, sizeof (struct camera_info));
2345 pthread_mutex_unlock(&gCamLock);
2346 return rc;
2347 }
2348
2349 /*===========================================================================
2350 * FUNCTION : getCamHalCapabilities
2351 *
2352 * DESCRIPTION: get the HAL capabilities structure
2353 *
2354 * PARAMETERS :
2355 * @cameraId : camera Id
2356 *
2357 * RETURN : capability structure of respective camera
2358 *
2359 *==========================================================================*/
getCamHalCapabilities()2360 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
2361 {
2362 return gCamCapability[mCameraId];
2363 }
2364
2365 /*===========================================================================
2366 * FUNCTION : getBufNumRequired
2367 *
2368 * DESCRIPTION: return number of stream buffers needed for given stream type
2369 *
2370 * PARAMETERS :
2371 * @stream_type : type of stream
2372 *
2373 * RETURN : number of buffers needed
2374 *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)2375 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
2376 {
2377 int bufferCnt = 0;
2378 int minCaptureBuffers = mParameters.getNumOfSnapshots();
2379 char value[PROPERTY_VALUE_MAX];
2380 bool raw_yuv = false;
2381 int persist_cnt = 0;
2382
2383 int zslQBuffers = mParameters.getZSLQueueDepth();
2384
2385 int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
2386 CAMERA_MIN_JPEG_ENCODING_BUFFERS;
2387
2388 int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
2389 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2390 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2391 mParameters.getNumOfExtraBuffersForImageProc() +
2392 EXTRA_ZSL_PREVIEW_STREAM_BUF;
2393
2394 int minUndequeCount = 0;
2395 if (!isNoDisplayMode()) {
2396 if(mPreviewWindow != NULL) {
2397 if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
2398 != 0) {
2399 LOGW("get_min_undequeued_buffer_count failed");
2400 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
2401 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2402 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2403 }
2404 } else {
2405 //preview window might not be set at this point. So, query directly
2406 //from BufferQueue implementation of gralloc buffers.
2407 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2408 //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
2409 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2410 }
2411 if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
2412 // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
2413 // and so change the MACRO as per minUndequeCount
2414 LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
2415 minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
2416 }
2417 }
2418
2419 LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
2420 "maxStreamBuf = %d minUndequeCount = %d",
2421 minCaptureBuffers, zslQBuffers, minCircularBufNum,
2422 maxStreamBuf, minUndequeCount);
2423 // Get buffer count for the particular stream type
2424 switch (stream_type) {
2425 case CAM_STREAM_TYPE_PREVIEW:
2426 {
2427 if (mParameters.isZSLMode()) {
2428 // We need to add two extra streming buffers to add
2429 // flexibility in forming matched super buf in ZSL queue.
2430 // with number being 'zslQBuffers + minCircularBufNum'
2431 // we see preview buffers sometimes get dropped at CPP
2432 // and super buf is not forming in ZSL Q for long time.
2433
2434 bufferCnt = zslQBuffers + minCircularBufNum +
2435 mParameters.getNumOfExtraBuffersForImageProc() +
2436 mParameters.getNumOfExtraBuffersForPreview() +
2437 mParameters.getNumOfExtraHDRInBufsIfNeeded();
2438 } else {
2439 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
2440 mParameters.getMaxUnmatchedFramesInQueue() +
2441 mParameters.getNumOfExtraBuffersForPreview();
2442 }
2443 // ISP allocates native preview buffers and so reducing same from HAL allocation
2444 if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
2445 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2446
2447 if (mParameters.getRecordingHintValue() == true)
2448 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
2449
2450 // Add the display minUndequeCount count on top of camera requirement
2451 bufferCnt += minUndequeCount;
2452
2453 property_get("persist.camera.preview_yuv", value, "0");
2454 persist_cnt = atoi(value);
2455 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2456 && (bufferCnt < persist_cnt)) {
2457 bufferCnt = persist_cnt;
2458 }
2459 }
2460 break;
2461 case CAM_STREAM_TYPE_POSTVIEW:
2462 {
2463 bufferCnt = minCaptureBuffers +
2464 mParameters.getMaxUnmatchedFramesInQueue() +
2465 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2466 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2467 mParameters.getNumOfExtraBuffersForImageProc();
2468
2469 if (bufferCnt > maxStreamBuf) {
2470 bufferCnt = maxStreamBuf;
2471 }
2472 bufferCnt += minUndequeCount;
2473 }
2474 break;
2475 case CAM_STREAM_TYPE_SNAPSHOT:
2476 {
2477 if (mParameters.isZSLMode() || mLongshotEnabled) {
2478 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
2479 !mLongshotEnabled) {
2480 // Single ZSL snapshot case
2481 bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
2482 mParameters.getNumOfExtraBuffersForImageProc();
2483 }
2484 else {
2485 // ZSL Burst or Longshot case
2486 bufferCnt = zslQBuffers + minCircularBufNum +
2487 mParameters.getNumOfExtraBuffersForImageProc();
2488 }
2489 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2490 //ISP allocates native buffers in YUV case
2491 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2492 }
2493 } else {
2494 bufferCnt = minCaptureBuffers +
2495 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2496 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2497 mParameters.getNumOfExtraBuffersForImageProc();
2498
2499 if (bufferCnt > maxStreamBuf) {
2500 bufferCnt = maxStreamBuf;
2501 }
2502 }
2503 }
2504 break;
2505 case CAM_STREAM_TYPE_RAW:
2506 property_get("persist.camera.raw_yuv", value, "0");
2507 raw_yuv = atoi(value) > 0 ? true : false;
2508
2509 if (isRdiMode() || raw_yuv) {
2510 bufferCnt = zslQBuffers + minCircularBufNum;
2511 } else if (mParameters.isZSLMode()) {
2512 bufferCnt = zslQBuffers + minCircularBufNum;
2513 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2514 //ISP allocates native buffers in YUV case
2515 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2516 }
2517
2518 } else {
2519 bufferCnt = minCaptureBuffers +
2520 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2521 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2522 mParameters.getNumOfExtraBuffersForImageProc();
2523
2524 if (bufferCnt > maxStreamBuf) {
2525 bufferCnt = maxStreamBuf;
2526 }
2527 }
2528
2529 property_get("persist.camera.preview_raw", value, "0");
2530 persist_cnt = atoi(value);
2531 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2532 && (bufferCnt < persist_cnt)) {
2533 bufferCnt = persist_cnt;
2534 }
2535 property_get("persist.camera.video_raw", value, "0");
2536 persist_cnt = atoi(value);
2537 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2538 && (bufferCnt < persist_cnt)) {
2539 bufferCnt = persist_cnt;
2540 }
2541
2542 break;
2543 case CAM_STREAM_TYPE_VIDEO:
2544 {
2545 if (mParameters.getBufBatchCount()) {
2546 //Video Buffer in case of HFR or camera batching..
2547 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
2548 } else if (mParameters.getVideoBatchSize()) {
2549 //Video Buffer count only for HAL to HAL batching.
2550 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
2551 * mParameters.getVideoBatchSize());
2552 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
2553 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2554 }
2555 } else {
2556 // No batching enabled.
2557 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2558 }
2559
2560 bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
2561 //if its 4K encoding usecase, then add extra buffer
2562 cam_dimension_t dim;
2563 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
2564 if (is4k2kResolution(&dim)) {
2565 //get additional buffer count
2566 property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
2567 bufferCnt += atoi(value);
2568 }
2569 }
2570 break;
2571 case CAM_STREAM_TYPE_METADATA:
2572 {
2573 if (mParameters.isZSLMode()) {
2574 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
2575 bufferCnt = zslQBuffers + minCircularBufNum +
2576 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2577 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2578 mParameters.getNumOfExtraBuffersForImageProc() +
2579 EXTRA_ZSL_PREVIEW_STREAM_BUF;
2580 } else {
2581 bufferCnt = minCaptureBuffers +
2582 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2583 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2584 mParameters.getMaxUnmatchedFramesInQueue() +
2585 CAMERA_MIN_STREAMING_BUFFERS +
2586 mParameters.getNumOfExtraBuffersForImageProc();
2587
2588 if (bufferCnt > zslQBuffers + minCircularBufNum) {
2589 bufferCnt = zslQBuffers + minCircularBufNum;
2590 }
2591 }
2592 if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
2593 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
2594 }
2595 }
2596 break;
2597 case CAM_STREAM_TYPE_OFFLINE_PROC:
2598 {
2599 bufferCnt = minCaptureBuffers;
2600 // One of the ubifocus buffers is miscellaneous buffer
2601 if (mParameters.isUbiRefocus()) {
2602 bufferCnt -= 1;
2603 }
2604 if (mLongshotEnabled) {
2605 bufferCnt = mParameters.getLongshotStages();
2606 }
2607 }
2608 break;
2609 case CAM_STREAM_TYPE_CALLBACK:
2610 bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
2611 break;
2612 case CAM_STREAM_TYPE_ANALYSIS:
2613 case CAM_STREAM_TYPE_DEFAULT:
2614 case CAM_STREAM_TYPE_MAX:
2615 default:
2616 bufferCnt = 0;
2617 break;
2618 }
2619
2620 LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
2621 if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
2622 LOGW("Buffer count %d for stream type %d exceeds limit %d",
2623 bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
2624 return CAM_MAX_NUM_BUFS_PER_STREAM;
2625 }
2626
2627 return (uint8_t)bufferCnt;
2628 }
2629
2630 /*===========================================================================
2631 * FUNCTION : allocateStreamBuf
2632 *
2633 * DESCRIPTION: alocate stream buffers
2634 *
2635 * PARAMETERS :
2636 * @stream_type : type of stream
2637 * @size : size of buffer
2638 * @stride : stride of buffer
2639 * @scanline : scanline of buffer
2640 * @bufferCnt : [IN/OUT] minimum num of buffers to be allocated.
2641 * could be modified during allocation if more buffers needed
2642 *
2643 * RETURN : ptr to a memory obj that holds stream buffers.
2644 * NULL if failed
2645 *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,size_t size,int stride,int scanline,uint8_t & bufferCnt)2646 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
2647 cam_stream_type_t stream_type, size_t size, int stride, int scanline,
2648 uint8_t &bufferCnt)
2649 {
2650 int rc = NO_ERROR;
2651 QCameraMemory *mem = NULL;
2652 bool bCachedMem = QCAMERA_ION_USE_CACHE;
2653 bool bPoolMem = false;
2654 char value[PROPERTY_VALUE_MAX];
2655 property_get("persist.camera.mem.usepool", value, "1");
2656 if (atoi(value) == 1) {
2657 bPoolMem = true;
2658 }
2659
2660 // Allocate stream buffer memory object
2661 switch (stream_type) {
2662 case CAM_STREAM_TYPE_PREVIEW:
2663 {
2664 if (isNoDisplayMode()) {
2665 mem = new QCameraStreamMemory(mGetMemory,
2666 bCachedMem,
2667 (bPoolMem) ? &m_memoryPool : NULL,
2668 stream_type);
2669 } else {
2670 cam_dimension_t dim;
2671 int minFPS, maxFPS;
2672 QCameraGrallocMemory *grallocMemory =
2673 new QCameraGrallocMemory(mGetMemory);
2674
2675 mParameters.getStreamDimension(stream_type, dim);
2676 /* we are interested only in maxfps here */
2677 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
2678 int usage = 0;
2679 if(mParameters.isUBWCEnabled()) {
2680 cam_format_t fmt;
2681 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
2682 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
2683 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
2684 }
2685 }
2686 if (grallocMemory) {
2687 grallocMemory->setMappable(
2688 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
2689 grallocMemory->setWindowInfo(mPreviewWindow,
2690 dim.width,dim.height, stride, scanline,
2691 mParameters.getPreviewHalPixelFormat(),
2692 maxFPS, usage);
2693 pthread_mutex_lock(&mGrallocLock);
2694 if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
2695 mEnqueuedBuffers = (bufferCnt -
2696 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
2697 } else {
2698 mEnqueuedBuffers = 0;
2699 }
2700 pthread_mutex_unlock(&mGrallocLock);
2701 }
2702 mem = grallocMemory;
2703 }
2704 }
2705 break;
2706 case CAM_STREAM_TYPE_POSTVIEW:
2707 {
2708 if (isNoDisplayMode() || isPreviewRestartEnabled()) {
2709 mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
2710 } else {
2711 cam_dimension_t dim;
2712 int minFPS, maxFPS;
2713 QCameraGrallocMemory *grallocMemory =
2714 new QCameraGrallocMemory(mGetMemory);
2715
2716 mParameters.getStreamDimension(stream_type, dim);
2717 /* we are interested only in maxfps here */
2718 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
2719 if (grallocMemory) {
2720 grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
2721 dim.height, stride, scanline,
2722 mParameters.getPreviewHalPixelFormat(), maxFPS);
2723 }
2724 mem = grallocMemory;
2725 }
2726 }
2727 break;
2728 case CAM_STREAM_TYPE_ANALYSIS:
2729 case CAM_STREAM_TYPE_SNAPSHOT:
2730 case CAM_STREAM_TYPE_RAW:
2731 case CAM_STREAM_TYPE_OFFLINE_PROC:
2732 mem = new QCameraStreamMemory(mGetMemory,
2733 bCachedMem,
2734 (bPoolMem) ? &m_memoryPool : NULL,
2735 stream_type);
2736 break;
2737 case CAM_STREAM_TYPE_METADATA:
2738 {
2739 if (mMetadataMem == NULL) {
2740 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
2741 } else {
2742 mem = mMetadataMem;
2743 mMetadataMem = NULL;
2744
2745 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
2746 if (numAdditionalBuffers > 0) {
2747 rc = mem->allocateMore(numAdditionalBuffers, size);
2748 if (rc != NO_ERROR) {
2749 LOGE("Failed to allocate additional buffers, "
2750 "but attempting to proceed.");
2751 }
2752 }
2753 bufferCnt = mem->getCnt();
2754 // The memory is already allocated and initialized, so
2755 // simply return here.
2756 return mem;
2757 }
2758 }
2759 break;
2760 case CAM_STREAM_TYPE_VIDEO:
2761 {
2762 //Use uncached allocation by default
2763 if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
2764 mParameters.isHighQualityNoiseReductionMode()) {
2765 bCachedMem = QCAMERA_ION_USE_CACHE;
2766 }
2767 else {
2768 bCachedMem = QCAMERA_ION_USE_NOCACHE;
2769 }
2770
2771 QCameraVideoMemory *videoMemory = NULL;
2772 if (mParameters.getVideoBatchSize()) {
2773 videoMemory = new QCameraVideoMemory(
2774 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
2775 if (videoMemory == NULL) {
2776 LOGE("Out of memory for video batching obj");
2777 return NULL;
2778 }
2779 /*
2780 * numFDs = BATCH size
2781 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
2782 */
2783 rc = videoMemory->allocateMeta(
2784 CAMERA_MIN_VIDEO_BATCH_BUFFERS,
2785 mParameters.getVideoBatchSize(),
2786 VIDEO_METADATA_NUM_INTS);
2787 if (rc < 0) {
2788 delete videoMemory;
2789 return NULL;
2790 }
2791 } else {
2792 videoMemory =
2793 new QCameraVideoMemory(mGetMemory, bCachedMem);
2794 if (videoMemory == NULL) {
2795 LOGE("Out of memory for video obj");
2796 return NULL;
2797 }
2798 }
2799
2800 int usage = 0;
2801 cam_format_t fmt;
2802 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
2803 if (mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
2804 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
2805 }
2806 videoMemory->setVideoInfo(usage, fmt);
2807 mem = videoMemory;
2808 }
2809 break;
2810 case CAM_STREAM_TYPE_CALLBACK:
2811 mem = new QCameraStreamMemory(mGetMemory,
2812 bCachedMem,
2813 (bPoolMem) ? &m_memoryPool : NULL,
2814 stream_type);
2815 break;
2816 case CAM_STREAM_TYPE_DEFAULT:
2817 case CAM_STREAM_TYPE_MAX:
2818 default:
2819 break;
2820 }
2821 if (!mem) {
2822 return NULL;
2823 }
2824
2825 if (bufferCnt > 0) {
2826 if (mParameters.isSecureMode() &&
2827 (stream_type == CAM_STREAM_TYPE_RAW) &&
2828 (mParameters.isRdiMode())) {
2829 LOGD("Allocating %d secure buffers of size %d ", bufferCnt, size);
2830 rc = mem->allocate(bufferCnt, size, SECURE);
2831 } else {
2832 rc = mem->allocate(bufferCnt, size, NON_SECURE);
2833 }
2834 if (rc < 0) {
2835 delete mem;
2836 return NULL;
2837 }
2838 bufferCnt = mem->getCnt();
2839 }
2840 LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d",
2841 rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem);
2842 return mem;
2843 }
2844
2845 /*===========================================================================
2846 * FUNCTION : allocateMoreStreamBuf
2847 *
2848 * DESCRIPTION: alocate more stream buffers from the memory object
2849 *
2850 * PARAMETERS :
2851 * @mem_obj : memory object ptr
2852 * @size : size of buffer
2853 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated.
2854 * output will be the number of total buffers
2855 *
2856 * RETURN : int32_t type of status
2857 * NO_ERROR -- success
2858 * none-zero failure code
2859 *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,size_t size,uint8_t & bufferCnt)2860 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
2861 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
2862 {
2863 int rc = NO_ERROR;
2864
2865 if (bufferCnt > 0) {
2866 rc = mem_obj->allocateMore(bufferCnt, size);
2867 bufferCnt = mem_obj->getCnt();
2868 }
2869 return rc;
2870 }
2871
2872 /*===========================================================================
2873 * FUNCTION : allocateMiscBuf
2874 *
2875 * DESCRIPTION: alocate miscellaneous buffer
2876 *
2877 * PARAMETERS :
2878 * @streamInfo : stream info
2879 *
2880 * RETURN : ptr to a memory obj that holds stream info buffer.
2881 * NULL if failed
2882 *==========================================================================*/
allocateMiscBuf(cam_stream_info_t * streamInfo)2883 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
2884 cam_stream_info_t *streamInfo)
2885 {
2886 int rc = NO_ERROR;
2887 uint8_t bufNum = 0;
2888 size_t bufSize = 0;
2889 QCameraHeapMemory *miscBuf = NULL;
2890 uint32_t feature_mask =
2891 streamInfo->reprocess_config.pp_feature_config.feature_mask;
2892
2893 switch (streamInfo->stream_type) {
2894 case CAM_STREAM_TYPE_OFFLINE_PROC:
2895 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
2896 bufNum = 1;
2897 bufSize = mParameters.getTPMaxMetaSize();
2898 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
2899 bufNum = 1;
2900 bufSize = mParameters.getRefocusMaxMetaSize();
2901 }
2902 break;
2903 default:
2904 break;
2905 }
2906
2907 if (bufNum && bufSize) {
2908 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
2909
2910 if (!miscBuf) {
2911 LOGE("Unable to allocate miscBuf object");
2912 return NULL;
2913 }
2914
2915 rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE);
2916 if (rc < 0) {
2917 LOGE("Failed to allocate misc buffer memory");
2918 delete miscBuf;
2919 return NULL;
2920 }
2921 }
2922
2923 return miscBuf;
2924 }
2925
2926 /*===========================================================================
2927 * FUNCTION : allocateStreamInfoBuf
2928 *
2929 * DESCRIPTION: alocate stream info buffer
2930 *
2931 * PARAMETERS :
2932 * @stream_type : type of stream
2933 *
2934 * RETURN : ptr to a memory obj that holds stream info buffer.
2935 * NULL if failed
2936 *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type)2937 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
2938 cam_stream_type_t stream_type)
2939 {
2940 int rc = NO_ERROR;
2941 char value[PROPERTY_VALUE_MAX];
2942 bool raw_yuv = false;
2943
2944 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
2945 if (!streamInfoBuf) {
2946 LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
2947 return NULL;
2948 }
2949
2950 rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE);
2951 if (rc < 0) {
2952 LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
2953 delete streamInfoBuf;
2954 return NULL;
2955 }
2956
2957 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
2958 memset(streamInfo, 0, sizeof(cam_stream_info_t));
2959 streamInfo->stream_type = stream_type;
2960 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
2961 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
2962 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
2963 streamInfo->num_bufs = getBufNumRequired(stream_type);
2964 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
2965 streamInfo->is_secure = NON_SECURE;
2966
2967 switch (stream_type) {
2968 case CAM_STREAM_TYPE_SNAPSHOT:
2969 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
2970 mLongshotEnabled) {
2971 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
2972 } else {
2973 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
2974 streamInfo->num_of_burst = (uint8_t)
2975 (mParameters.getNumOfSnapshots()
2976 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
2977 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
2978 + mParameters.getNumOfExtraBuffersForImageProc());
2979 }
2980 break;
2981 case CAM_STREAM_TYPE_RAW:
2982 property_get("persist.camera.raw_yuv", value, "0");
2983 raw_yuv = atoi(value) > 0 ? true : false;
2984 if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) {
2985 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
2986 } else {
2987 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
2988 streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
2989 }
2990 if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
2991 streamInfo->is_secure = SECURE;
2992 } else {
2993 streamInfo->is_secure = NON_SECURE;
2994 }
2995 break;
2996 case CAM_STREAM_TYPE_POSTVIEW:
2997 if (mLongshotEnabled) {
2998 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
2999 } else {
3000 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3001 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
3002 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3003 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3004 + mParameters.getNumOfExtraBuffersForImageProc());
3005 }
3006 break;
3007 case CAM_STREAM_TYPE_VIDEO:
3008 streamInfo->dis_enable = mParameters.isDISEnabled();
3009 if (mParameters.getBufBatchCount()) {
3010 //Update stream info structure with batch mode info
3011 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
3012 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
3013 streamInfo->user_buf_info.size =
3014 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
3015 cam_fps_range_t pFpsRange;
3016 mParameters.getHfrFps(pFpsRange);
3017 streamInfo->user_buf_info.frameInterval =
3018 (long)((1000/pFpsRange.video_max_fps) * 1000);
3019 LOGH("Video Batch Count = %d, interval = %d",
3020 streamInfo->user_buf_info.frame_buf_cnt,
3021 streamInfo->user_buf_info.frameInterval);
3022 }
3023 case CAM_STREAM_TYPE_PREVIEW:
3024 if (mParameters.getRecordingHintValue()) {
3025 if(mParameters.isDISEnabled()) {
3026 streamInfo->is_type = mParameters.getISType();
3027 } else {
3028 streamInfo->is_type = IS_TYPE_NONE;
3029 }
3030 }
3031 if (mParameters.isSecureMode()) {
3032 streamInfo->is_secure = SECURE;
3033 }
3034 break;
3035 case CAM_STREAM_TYPE_ANALYSIS:
3036 streamInfo->noFrameExpected = 1;
3037 break;
3038 default:
3039 break;
3040 }
3041
3042 // Update feature mask
3043 mParameters.updatePpFeatureMask(stream_type);
3044
3045 // Get feature mask
3046 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
3047
3048 // Update pp config
3049 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
3050 int flipMode = mParameters.getFlipMode(stream_type);
3051 if (flipMode > 0) {
3052 streamInfo->pp_config.flip = (uint32_t)flipMode;
3053 }
3054 }
3055 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3056 streamInfo->pp_config.sharpness = mParameters.getSharpness();
3057 }
3058 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
3059 streamInfo->pp_config.effect = mParameters.getEffectValue();
3060 }
3061
3062 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
3063 streamInfo->pp_config.denoise2d.denoise_enable = 1;
3064 streamInfo->pp_config.denoise2d.process_plates =
3065 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
3066 }
3067
3068 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
3069 CAM_STREAM_TYPE_RAW == stream_type))) {
3070 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3071 CAM_QCOM_FEATURE_CROP)
3072 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
3073 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3074 CAM_QCOM_FEATURE_SCALE)
3075 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
3076 }
3077
3078 LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x\n",
3079 stream_type, streamInfo->fmt, streamInfo->dim.width,
3080 streamInfo->dim.height, streamInfo->num_bufs,
3081 streamInfo->pp_config.feature_mask);
3082
3083 return streamInfoBuf;
3084 }
3085
3086 /*===========================================================================
3087 * FUNCTION : allocateStreamUserBuf
3088 *
3089 * DESCRIPTION: allocate user ptr for stream buffers
3090 *
3091 * PARAMETERS :
3092 * @streamInfo : stream info structure
3093 *
3094 * RETURN : ptr to a memory obj that holds stream info buffer.
3095 * NULL if failed
3096
3097 *==========================================================================*/
allocateStreamUserBuf(cam_stream_info_t * streamInfo)3098 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
3099 cam_stream_info_t *streamInfo)
3100 {
3101 int rc = NO_ERROR;
3102 QCameraMemory *mem = NULL;
3103 int size = 0;
3104
3105 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
3106 LOGE("Stream is not in BATCH mode. Invalid Stream");
3107 return NULL;
3108 }
3109
3110 // Allocate stream user buffer memory object
3111 switch (streamInfo->stream_type) {
3112 case CAM_STREAM_TYPE_VIDEO: {
3113 QCameraVideoMemory *video_mem = new QCameraVideoMemory(
3114 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
3115 if (video_mem == NULL) {
3116 LOGE("Out of memory for video obj");
3117 return NULL;
3118 }
3119 /*
3120 * numFDs = BATCH size
3121 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3122 */
3123 rc = video_mem->allocateMeta(streamInfo->num_bufs,
3124 mParameters.getBufBatchCount(), VIDEO_METADATA_NUM_INTS);
3125 if (rc < 0) {
3126 LOGE("allocateMeta failed");
3127 delete video_mem;
3128 return NULL;
3129 }
3130 int usage = 0;
3131 cam_format_t fmt;
3132 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
3133 if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3134 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3135 }
3136 video_mem->setVideoInfo(usage, fmt);
3137 mem = static_cast<QCameraMemory *>(video_mem);
3138 }
3139 break;
3140
3141 case CAM_STREAM_TYPE_PREVIEW:
3142 case CAM_STREAM_TYPE_POSTVIEW:
3143 case CAM_STREAM_TYPE_ANALYSIS:
3144 case CAM_STREAM_TYPE_SNAPSHOT:
3145 case CAM_STREAM_TYPE_RAW:
3146 case CAM_STREAM_TYPE_METADATA:
3147 case CAM_STREAM_TYPE_OFFLINE_PROC:
3148 case CAM_STREAM_TYPE_CALLBACK:
3149 LOGE("Stream type Not supported.for BATCH processing");
3150 break;
3151
3152 case CAM_STREAM_TYPE_DEFAULT:
3153 case CAM_STREAM_TYPE_MAX:
3154 default:
3155 break;
3156 }
3157 if (!mem) {
3158 LOGE("Failed to allocate mem");
3159 return NULL;
3160 }
3161
3162 /*Size of this buffer will be number of batch buffer */
3163 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
3164 CAM_PAD_TO_4K);
3165
3166 LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
3167
3168 if (size > 0) {
3169 // Allocating one buffer for all batch buffers
3170 rc = mem->allocate(1, size, NON_SECURE);
3171 if (rc < 0) {
3172 delete mem;
3173 return NULL;
3174 }
3175 }
3176 return mem;
3177 }
3178
3179
3180 /*===========================================================================
3181 * FUNCTION : waitForDeferredAlloc
3182 *
3183 * DESCRIPTION: Wait for deferred allocation, if applicable
3184 * (applicable only for metadata buffers so far)
3185 *
3186 * PARAMETERS :
3187 * @stream_type : type of stream to (possibly) wait for
3188 *
3189 * RETURN : None
3190 *==========================================================================*/
waitForDeferredAlloc(cam_stream_type_t stream_type)3191 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
3192 {
3193 if (stream_type == CAM_STREAM_TYPE_METADATA) {
3194 waitDeferredWork(mMetadataAllocJob);
3195 }
3196 }
3197
3198
3199 /*===========================================================================
3200 * FUNCTION : setPreviewWindow
3201 *
3202 * DESCRIPTION: set preview window impl
3203 *
3204 * PARAMETERS :
3205 * @window : ptr to window ops table struct
3206 *
3207 * RETURN : int32_t type of status
3208 * NO_ERROR -- success
3209 * none-zero failure code
3210 *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)3211 int QCamera2HardwareInterface::setPreviewWindow(
3212 struct preview_stream_ops *window)
3213 {
3214 mPreviewWindow = window;
3215 return NO_ERROR;
3216 }
3217
3218 /*===========================================================================
3219 * FUNCTION : setCallBacks
3220 *
3221 * DESCRIPTION: set callbacks impl
3222 *
3223 * PARAMETERS :
3224 * @notify_cb : notify cb
3225 * @data_cb : data cb
3226 * @data_cb_timestamp : data cb with time stamp
3227 * @get_memory : request memory ops table
3228 * @user : user data ptr
3229 *
3230 * RETURN : int32_t type of status
3231 * NO_ERROR -- success
3232 * none-zero failure code
3233 *==========================================================================*/
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)3234 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
3235 camera_data_callback data_cb,
3236 camera_data_timestamp_callback data_cb_timestamp,
3237 camera_request_memory get_memory,
3238 void *user)
3239 {
3240 mNotifyCb = notify_cb;
3241 mDataCb = data_cb;
3242 mDataCbTimestamp = data_cb_timestamp;
3243 mGetMemory = get_memory;
3244 mCallbackCookie = user;
3245 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
3246 return NO_ERROR;
3247 }
3248
3249 /*===========================================================================
3250 * FUNCTION : setJpegCallBacks
3251 *
3252 * DESCRIPTION: set JPEG callbacks impl
3253 *
3254 * PARAMETERS :
3255 * @jpegCb : Jpeg callback method
3256 * @callbackCookie : callback cookie
3257 *
3258 * RETURN : int32_t type of status
3259 * NO_ERROR -- success
3260 * none-zero failure code
3261 *==========================================================================*/
setJpegCallBacks(jpeg_data_callback jpegCb,void * callbackCookie)3262 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
3263 void *callbackCookie)
3264 {
3265 LOGH("camera id %d", getCameraId());
3266 mJpegCb = jpegCb;
3267 mJpegCallbackCookie = callbackCookie;
3268 m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
3269 }
3270
3271 /*===========================================================================
3272 * FUNCTION : enableMsgType
3273 *
3274 * DESCRIPTION: enable msg type impl
3275 *
3276 * PARAMETERS :
3277 * @msg_type : msg type mask to be enabled
3278 *
3279 * RETURN : int32_t type of status
3280 * NO_ERROR -- success
3281 * none-zero failure code
3282 *==========================================================================*/
enableMsgType(int32_t msg_type)3283 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
3284 {
3285 int32_t rc = NO_ERROR;
3286
3287 if (mParameters.isUBWCEnabled()) {
3288 /*Need Special CALLBACK stream incase application requesting for
3289 Preview callback in UBWC case*/
3290 if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3291 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3292 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
3293 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3294 if (rc != NO_ERROR) {
3295 LOGE("START Callback Channel failed");
3296 }
3297 }
3298 }
3299 }
3300 mMsgEnabled |= msg_type;
3301 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3302 return rc;
3303 }
3304
3305 /*===========================================================================
3306 * FUNCTION : disableMsgType
3307 *
3308 * DESCRIPTION: disable msg type impl
3309 *
3310 * PARAMETERS :
3311 * @msg_type : msg type mask to be disabled
3312 *
3313 * RETURN : int32_t type of status
3314 * NO_ERROR -- success
3315 * none-zero failure code
3316 *==========================================================================*/
disableMsgType(int32_t msg_type)3317 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
3318 {
3319 int32_t rc = NO_ERROR;
3320
3321 if (mParameters.isUBWCEnabled()) {
3322 /*STOP CALLBACK STREAM*/
3323 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3324 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3325 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
3326 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3327 if (rc != NO_ERROR) {
3328 LOGE("STOP Callback Channel failed");
3329 }
3330 }
3331 }
3332 }
3333 mMsgEnabled &= ~msg_type;
3334 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3335 return rc;
3336 }
3337
3338 /*===========================================================================
3339 * FUNCTION : msgTypeEnabled
3340 *
3341 * DESCRIPTION: impl to determine if certain msg_type is enabled
3342 *
3343 * PARAMETERS :
3344 * @msg_type : msg type mask
3345 *
3346 * RETURN : 0 -- not enabled
3347 * none 0 -- enabled
3348 *==========================================================================*/
msgTypeEnabled(int32_t msg_type)3349 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
3350 {
3351 return (mMsgEnabled & msg_type);
3352 }
3353
3354 /*===========================================================================
3355 * FUNCTION : msgTypeEnabledWithLock
3356 *
3357 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
3358 *
3359 * PARAMETERS :
3360 * @msg_type : msg type mask
3361 *
3362 * RETURN : 0 -- not enabled
3363 * none 0 -- enabled
3364 *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)3365 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
3366 {
3367 int enabled = 0;
3368 lockAPI();
3369 enabled = mMsgEnabled & msg_type;
3370 unlockAPI();
3371 return enabled;
3372 }
3373
3374 /*===========================================================================
3375 * FUNCTION : startPreview
3376 *
3377 * DESCRIPTION: start preview impl
3378 *
3379 * PARAMETERS : none
3380 *
3381 * RETURN : int32_t type of status
3382 * NO_ERROR -- success
3383 * none-zero failure code
3384 *==========================================================================*/
startPreview()3385 int QCamera2HardwareInterface::startPreview()
3386 {
3387 KPI_ATRACE_CALL();
3388 int32_t rc = NO_ERROR;
3389
3390 LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
3391 mParameters.getRecordingHintValue());
3392
3393 m_perfLock.lock_acq();
3394
3395 updateThermalLevel((void *)&mThermalLevel);
3396
3397 setDisplayFrameSkip();
3398
3399 // start preview stream
3400 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
3401 rc = startChannel(QCAMERA_CH_TYPE_ZSL);
3402 } else {
3403 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3404 }
3405
3406 if (rc != NO_ERROR) {
3407 LOGE("failed to start channels");
3408 m_perfLock.lock_rel();
3409 return rc;
3410 }
3411
3412 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
3413 && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
3414 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3415 if (rc != NO_ERROR) {
3416 LOGE("failed to start callback stream");
3417 stopChannel(QCAMERA_CH_TYPE_ZSL);
3418 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3419 m_perfLock.lock_rel();
3420 return rc;
3421 }
3422 }
3423
3424 updatePostPreviewParameters();
3425 m_stateMachine.setPreviewCallbackNeeded(true);
3426
3427 // if job id is non-zero, that means the postproc init job is already
3428 // pending or complete
3429 if (mInitPProcJob == 0) {
3430 mInitPProcJob = deferPPInit();
3431 if (mInitPProcJob == 0) {
3432 LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
3433 mCameraHandle);
3434 rc = -ENOMEM;
3435 m_perfLock.lock_rel();
3436 return rc;
3437 }
3438 }
3439 m_perfLock.lock_rel();
3440
3441 if (rc == NO_ERROR) {
3442 // Set power Hint for preview
3443 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
3444 }
3445
3446 LOGI("X rc = %d", rc);
3447 return rc;
3448 }
3449
updatePostPreviewParameters()3450 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
3451 // Enable OIS only in Camera mode and 4k2k camcoder mode
3452 int32_t rc = NO_ERROR;
3453 rc = mParameters.updateOisValue(1);
3454 return NO_ERROR;
3455 }
3456
3457 /*===========================================================================
3458 * FUNCTION : stopPreview
3459 *
3460 * DESCRIPTION: stop preview impl
3461 *
3462 * PARAMETERS : none
3463 *
3464 * RETURN : int32_t type of status
3465 * NO_ERROR -- success
3466 * none-zero failure code
3467 *==========================================================================*/
stopPreview()3468 int QCamera2HardwareInterface::stopPreview()
3469 {
3470 KPI_ATRACE_CALL();
3471 LOGI("E");
3472 mNumPreviewFaces = -1;
3473 mActiveAF = false;
3474
3475 // Disable power Hint for preview
3476 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
3477
3478 m_perfLock.lock_acq();
3479
3480 // stop preview stream
3481 stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3482 stopChannel(QCAMERA_CH_TYPE_ZSL);
3483 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3484 stopChannel(QCAMERA_CH_TYPE_RAW);
3485
3486 m_cbNotifier.flushPreviewNotifications();
3487 //add for ts makeup
3488 #ifdef TARGET_TS_MAKEUP
3489 ts_makeup_finish();
3490 #endif
3491 // delete all channels from preparePreview
3492 unpreparePreview();
3493
3494 m_perfLock.lock_rel();
3495
3496 LOGI("X");
3497 return NO_ERROR;
3498 }
3499
3500 /*===========================================================================
3501 * FUNCTION : storeMetaDataInBuffers
3502 *
3503 * DESCRIPTION: enable store meta data in buffers for video frames impl
3504 *
3505 * PARAMETERS :
3506 * @enable : flag if need enable
3507 *
3508 * RETURN : int32_t type of status
3509 * NO_ERROR -- success
3510 * none-zero failure code
3511 *==========================================================================*/
storeMetaDataInBuffers(int enable)3512 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
3513 {
3514 mStoreMetaDataInFrame = enable;
3515 return NO_ERROR;
3516 }
3517
3518 /*===========================================================================
3519 * FUNCTION : preStartRecording
3520 *
3521 * DESCRIPTION: Prepare start recording impl
3522 *
3523 * PARAMETERS : none
3524 *
3525 * RETURN : int32_t type of status
3526 * NO_ERROR -- success
3527 * none-zero failure code
3528 *==========================================================================*/
preStartRecording()3529 int QCamera2HardwareInterface::preStartRecording()
3530 {
3531 int32_t rc = NO_ERROR;
3532 LOGH("E");
3533 if (mParameters.getRecordingHintValue() == false) {
3534
3535 // Give HWI control to restart preview only in single camera mode.
3536 // In dual-cam mode, this control belongs to muxer.
3537 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
3538 LOGH("start recording when hint is false, stop preview first");
3539 stopPreview();
3540
3541 // Set recording hint to TRUE
3542 mParameters.updateRecordingHintValue(TRUE);
3543 rc = preparePreview();
3544 if (rc == NO_ERROR) {
3545 rc = startPreview();
3546 }
3547 }
3548 else
3549 {
3550 // For dual cam mode, update the flag mPreviewRestartNeeded to true
3551 // Restart control will be handled by muxer.
3552 mPreviewRestartNeeded = true;
3553 }
3554 }
3555
3556 LOGH("X rc = %d", rc);
3557 return rc;
3558 }
3559
3560 /*===========================================================================
3561 * FUNCTION : startRecording
3562 *
3563 * DESCRIPTION: start recording impl
3564 *
3565 * PARAMETERS : none
3566 *
3567 * RETURN : int32_t type of status
3568 * NO_ERROR -- success
3569 * none-zero failure code
3570 *==========================================================================*/
startRecording()3571 int QCamera2HardwareInterface::startRecording()
3572 {
3573 int32_t rc = NO_ERROR;
3574
3575 LOGI("E");
3576 //link meta stream with video channel if low power mode.
3577 if (isLowPowerMode()) {
3578 // Find and try to link a metadata stream from preview channel
3579 QCameraChannel *pMetaChannel = NULL;
3580 QCameraStream *pMetaStream = NULL;
3581 QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
3582
3583 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
3584 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3585 uint32_t streamNum = pMetaChannel->getNumOfStreams();
3586 QCameraStream *pStream = NULL;
3587 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
3588 pStream = pMetaChannel->getStreamByIndex(i);
3589 if ((NULL != pStream) &&
3590 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
3591 pMetaStream = pStream;
3592 break;
3593 }
3594 }
3595 }
3596
3597 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
3598 rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
3599 if (NO_ERROR != rc) {
3600 LOGW("Metadata stream link failed %d", rc);
3601 }
3602 }
3603 }
3604
3605 if (rc == NO_ERROR) {
3606 rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
3607 }
3608
3609 if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
3610 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
3611 if (!mParameters.is4k2kVideoResolution()) {
3612 // Find and try to link a metadata stream from preview channel
3613 QCameraChannel *pMetaChannel = NULL;
3614 QCameraStream *pMetaStream = NULL;
3615
3616 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
3617 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3618 uint32_t streamNum = pMetaChannel->getNumOfStreams();
3619 QCameraStream *pStream = NULL;
3620 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
3621 pStream = pMetaChannel->getStreamByIndex(i);
3622 if ((NULL != pStream) &&
3623 (CAM_STREAM_TYPE_METADATA ==
3624 pStream->getMyType())) {
3625 pMetaStream = pStream;
3626 break;
3627 }
3628 }
3629 }
3630
3631 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
3632 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
3633 if (NO_ERROR != rc) {
3634 LOGW("Metadata stream link failed %d", rc);
3635 }
3636 }
3637 }
3638 LOGH("START snapshot Channel for TNR processing");
3639 rc = pChannel->start();
3640 }
3641
3642 if (rc == NO_ERROR) {
3643 // Set power Hint for video encoding
3644 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
3645 }
3646
3647 LOGI("X rc = %d", rc);
3648 return rc;
3649 }
3650
3651 /*===========================================================================
3652 * FUNCTION : stopRecording
3653 *
3654 * DESCRIPTION: stop recording impl
3655 *
3656 * PARAMETERS : none
3657 *
3658 * RETURN : int32_t type of status
3659 * NO_ERROR -- success
3660 * none-zero failure code
3661 *==========================================================================*/
stopRecording()3662 int QCamera2HardwareInterface::stopRecording()
3663 {
3664 LOGI("E");
3665 // stop snapshot channel
3666 if (mParameters.isTNRSnapshotEnabled()) {
3667 LOGH("STOP snapshot Channel for TNR processing");
3668 stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3669 }
3670 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
3671
3672 // Disable power hint for video encoding
3673 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
3674
3675 LOGI("X rc = %d", rc);
3676 return rc;
3677 }
3678
3679 /*===========================================================================
3680 * FUNCTION : releaseRecordingFrame
3681 *
3682 * DESCRIPTION: return video frame impl
3683 *
3684 * PARAMETERS :
3685 * @opaque : ptr to video frame to be returned
3686 *
3687 * RETURN : int32_t type of status
3688 * NO_ERROR -- success
3689 * none-zero failure code
3690 *==========================================================================*/
releaseRecordingFrame(const void * opaque)3691 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
3692 {
3693 int32_t rc = UNKNOWN_ERROR;
3694 QCameraVideoChannel *pChannel =
3695 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
3696 LOGD("opaque data = %p",opaque);
3697 if(pChannel != NULL) {
3698 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
3699 }
3700 return rc;
3701 }
3702
3703 /*===========================================================================
3704 * FUNCTION : autoFocus
3705 *
3706 * DESCRIPTION: start auto focus impl
3707 *
3708 * PARAMETERS : none
3709 *
3710 * RETURN : int32_t type of status
3711 * NO_ERROR -- success
3712 * none-zero failure code
3713 *==========================================================================*/
autoFocus()3714 int QCamera2HardwareInterface::autoFocus()
3715 {
3716 int rc = NO_ERROR;
3717 cam_focus_mode_type focusMode = mParameters.getFocusMode();
3718 LOGH("E");
3719
3720 m_currentFocusState = CAM_AF_STATE_INACTIVE;
3721
3722 switch (focusMode) {
3723 case CAM_FOCUS_MODE_AUTO:
3724 case CAM_FOCUS_MODE_MACRO:
3725 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
3726 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
3727 mActiveAF = true;
3728 LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
3729 focusMode, m_currentFocusState);
3730 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
3731 break;
3732 case CAM_FOCUS_MODE_INFINITY:
3733 case CAM_FOCUS_MODE_FIXED:
3734 case CAM_FOCUS_MODE_EDOF:
3735 default:
3736 LOGI("No ops in focusMode (%d)", focusMode);
3737 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
3738 break;
3739 }
3740
3741 if (NO_ERROR != rc) {
3742 mActiveAF = false;
3743 }
3744 LOGH("X rc = %d", rc);
3745 return rc;
3746 }
3747
3748 /*===========================================================================
3749 * FUNCTION : cancelAutoFocus
3750 *
3751 * DESCRIPTION: cancel auto focus impl
3752 *
3753 * PARAMETERS : none
3754 *
3755 * RETURN : int32_t type of status
3756 * NO_ERROR -- success
3757 * none-zero failure code
3758 *==========================================================================*/
cancelAutoFocus()3759 int QCamera2HardwareInterface::cancelAutoFocus()
3760 {
3761 int rc = NO_ERROR;
3762 cam_focus_mode_type focusMode = mParameters.getFocusMode();
3763
3764 switch (focusMode) {
3765 case CAM_FOCUS_MODE_AUTO:
3766 case CAM_FOCUS_MODE_MACRO:
3767 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
3768 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
3769 mActiveAF = false;
3770 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
3771 break;
3772 case CAM_FOCUS_MODE_INFINITY:
3773 case CAM_FOCUS_MODE_FIXED:
3774 case CAM_FOCUS_MODE_EDOF:
3775 default:
3776 LOGD("No ops in focusMode (%d)", focusMode);
3777 break;
3778 }
3779 return rc;
3780 }
3781
3782 /*===========================================================================
3783 * FUNCTION : processUFDumps
3784 *
3785 * DESCRIPTION: process UF jpeg dumps for refocus support
3786 *
3787 * PARAMETERS :
3788 * @evt : payload of jpeg event, including information about jpeg encoding
3789 * status, jpeg size and so on.
3790 *
3791 * RETURN : int32_t type of status
3792 * NO_ERROR -- success
3793 * none-zero failure code
3794 *
3795 * NOTE : none
3796 *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)3797 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
3798 {
3799 bool ret = true;
3800 if (mParameters.isUbiRefocus()) {
3801 int index = (int)getOutputImageCount();
3802 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
3803 char name[FILENAME_MAX];
3804
3805 camera_memory_t *jpeg_mem = NULL;
3806 omx_jpeg_ouput_buf_t *jpeg_out = NULL;
3807 size_t dataLen;
3808 uint8_t *dataPtr;
3809 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
3810 LOGE("Init PProc Deferred work failed");
3811 return false;
3812 }
3813 if (!m_postprocessor.getJpegMemOpt()) {
3814 dataLen = evt->out_data.buf_filled_len;
3815 dataPtr = evt->out_data.buf_vaddr;
3816 } else {
3817 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
3818 if (!jpeg_out) {
3819 LOGE("Null pointer detected");
3820 return false;
3821 }
3822 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
3823 if (!jpeg_mem) {
3824 LOGE("Null pointer detected");
3825 return false;
3826 }
3827 dataPtr = (uint8_t *)jpeg_mem->data;
3828 dataLen = jpeg_mem->size;
3829 }
3830
3831 if (allFocusImage) {
3832 snprintf(name, sizeof(name), "AllFocusImage");
3833 index = -1;
3834 } else {
3835 snprintf(name, sizeof(name), "%d", 0);
3836 }
3837 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
3838 dataPtr, dataLen);
3839 LOGD("Dump the image %d %d allFocusImage %d",
3840 getOutputImageCount(), index, allFocusImage);
3841 setOutputImageCount(getOutputImageCount() + 1);
3842 if (!allFocusImage) {
3843 ret = false;
3844 }
3845 }
3846 return ret;
3847 }
3848
3849 /*===========================================================================
3850 * FUNCTION : unconfigureAdvancedCapture
3851 *
3852 * DESCRIPTION: unconfigure Advanced Capture.
3853 *
3854 * PARAMETERS : none
3855 *
3856 * RETURN : int32_t type of status
3857 * NO_ERROR -- success
3858 * none-zero failure code
3859 *==========================================================================*/
unconfigureAdvancedCapture()3860 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
3861 {
3862 int32_t rc = NO_ERROR;
3863
3864 if (mAdvancedCaptureConfigured) {
3865
3866 mAdvancedCaptureConfigured = false;
3867
3868 if(mIs3ALocked) {
3869 mParameters.set3ALock(false);
3870 mIs3ALocked = false;
3871 }
3872 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
3873 rc = mParameters.setToneMapMode(true, true);
3874 if (rc != NO_ERROR) {
3875 LOGW("Failed to enable tone map during HDR/AEBracketing");
3876 }
3877 mHDRBracketingEnabled = false;
3878 rc = mParameters.stopAEBracket();
3879 } else if ((mParameters.isChromaFlashEnabled())
3880 || (mFlashNeeded && !mLongshotEnabled)
3881 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
3882 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
3883 rc = mParameters.resetFrameCapture(TRUE);
3884 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
3885 rc = configureAFBracketing(false);
3886 } else if (mParameters.isOptiZoomEnabled()) {
3887 rc = mParameters.setAndCommitZoom(mZoomLevel);
3888 setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
3889 } else if (mParameters.isStillMoreEnabled()) {
3890 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
3891 stillmore_config.burst_count = 0;
3892 mParameters.setStillMoreSettings(stillmore_config);
3893
3894 /* If SeeMore is running, it will handle re-enabling tone map */
3895 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
3896 rc = mParameters.setToneMapMode(true, true);
3897 if (rc != NO_ERROR) {
3898 LOGW("Failed to enable tone map during StillMore");
3899 }
3900 }
3901
3902 /* Re-enable Tintless */
3903 mParameters.setTintless(true);
3904 } else {
3905 LOGW("No Advanced Capture feature enabled!!");
3906 rc = BAD_VALUE;
3907 }
3908 }
3909
3910 return rc;
3911 }
3912
3913 /*===========================================================================
3914 * FUNCTION : configureAdvancedCapture
3915 *
3916 * DESCRIPTION: configure Advanced Capture.
3917 *
3918 * PARAMETERS : none
3919 *
3920 * RETURN : int32_t type of status
3921 * NO_ERROR -- success
3922 * none-zero failure code
3923 *==========================================================================*/
configureAdvancedCapture()3924 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
3925 {
3926 LOGH("E");
3927 int32_t rc = NO_ERROR;
3928
3929 rc = mParameters.checkFeatureConcurrency();
3930 if (rc != NO_ERROR) {
3931 LOGE("Cannot support Advanced capture modes");
3932 return rc;
3933 }
3934
3935 setOutputImageCount(0);
3936 mInputCount = 0;
3937 mAdvancedCaptureConfigured = true;
3938 /* Display should be disabled for advanced modes */
3939 bool bSkipDisplay = true;
3940
3941 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
3942 // no Advance capture settings for Aux camera
3943 LOGH("X Secondary Camera, no need to process!! ");
3944 return rc;
3945 }
3946
3947 /* Do not stop display if in stillmore livesnapshot */
3948 if (mParameters.isStillMoreEnabled() &&
3949 mParameters.isSeeMoreEnabled()) {
3950 bSkipDisplay = false;
3951 }
3952 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
3953 rc = configureAFBracketing();
3954 } else if (mParameters.isOptiZoomEnabled()) {
3955 rc = configureOptiZoom();
3956 } else if(mParameters.isHDREnabled()) {
3957 rc = configureHDRBracketing();
3958 if (mHDRBracketingEnabled) {
3959 rc = mParameters.setToneMapMode(false, true);
3960 if (rc != NO_ERROR) {
3961 LOGW("Failed to disable tone map during HDR");
3962 }
3963 }
3964 } else if (mParameters.isAEBracketEnabled()) {
3965 rc = mParameters.setToneMapMode(false, true);
3966 if (rc != NO_ERROR) {
3967 LOGW("Failed to disable tone map during AEBracketing");
3968 }
3969 rc = configureAEBracketing();
3970 } else if (mParameters.isStillMoreEnabled()) {
3971 rc = configureStillMore();
3972 } else if ((mParameters.isChromaFlashEnabled())
3973 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
3974 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
3975 rc = mParameters.configFrameCapture(TRUE);
3976 } else if (mFlashNeeded && !mLongshotEnabled) {
3977 rc = mParameters.configFrameCapture(TRUE);
3978 bSkipDisplay = false;
3979 } else {
3980 LOGH("Advanced Capture feature not enabled!! ");
3981 mAdvancedCaptureConfigured = false;
3982 bSkipDisplay = false;
3983 }
3984
3985 LOGH("Stop preview temporarily for advanced captures");
3986 setDisplaySkip(bSkipDisplay);
3987
3988 LOGH("X rc = %d", rc);
3989 return rc;
3990 }
3991
3992 /*===========================================================================
3993 * FUNCTION : configureAFBracketing
3994 *
3995 * DESCRIPTION: configure AF Bracketing.
3996 *
3997 * PARAMETERS : none
3998 *
3999 * RETURN : int32_t type of status
4000 * NO_ERROR -- success
4001 * none-zero failure code
4002 *==========================================================================*/
configureAFBracketing(bool enable)4003 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
4004 {
4005 LOGH("E");
4006 int32_t rc = NO_ERROR;
4007 cam_af_bracketing_t *af_bracketing_need;
4008
4009 if (mParameters.isUbiRefocus()) {
4010 af_bracketing_need =
4011 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
4012 } else {
4013 af_bracketing_need =
4014 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
4015 }
4016
4017 //Enable AF Bracketing.
4018 cam_af_bracketing_t afBracket;
4019 memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
4020 afBracket.enable = enable;
4021 afBracket.burst_count = af_bracketing_need->burst_count;
4022
4023 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
4024 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
4025 LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
4026 }
4027 //Send cmd to backend to set AF Bracketing for Ubi Focus.
4028 rc = mParameters.commitAFBracket(afBracket);
4029 if ( NO_ERROR != rc ) {
4030 LOGE("cannot configure AF bracketing");
4031 return rc;
4032 }
4033 if (enable) {
4034 mParameters.set3ALock(true);
4035 mIs3ALocked = true;
4036 }
4037 LOGH("X rc = %d", rc);
4038 return rc;
4039 }
4040
4041 /*===========================================================================
4042 * FUNCTION : configureHDRBracketing
4043 *
4044 * DESCRIPTION: configure HDR Bracketing.
4045 *
4046 * PARAMETERS : none
4047 *
4048 * RETURN : int32_t type of status
4049 * NO_ERROR -- success
4050 * none-zero failure code
4051 *==========================================================================*/
configureHDRBracketing()4052 int32_t QCamera2HardwareInterface::configureHDRBracketing()
4053 {
4054 LOGH("E");
4055 int32_t rc = NO_ERROR;
4056
4057 cam_hdr_bracketing_info_t& hdrBracketingSetting =
4058 gCamCapability[mCameraId]->hdr_bracketing_setting;
4059
4060 // 'values' should be in "idx1,idx2,idx3,..." format
4061 uint32_t hdrFrameCount =
4062 hdrBracketingSetting.num_frames;
4063 LOGH("HDR values %d, %d frame count: %u",
4064 (int8_t) hdrBracketingSetting.exp_val.values[0],
4065 (int8_t) hdrBracketingSetting.exp_val.values[1],
4066 hdrFrameCount);
4067
4068 // Enable AE Bracketing for HDR
4069 cam_exp_bracketing_t aeBracket;
4070 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
4071 aeBracket.mode =
4072 hdrBracketingSetting.exp_val.mode;
4073
4074 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
4075 mHDRBracketingEnabled = true;
4076 }
4077
4078 String8 tmp;
4079 for (uint32_t i = 0; i < hdrFrameCount; i++) {
4080 tmp.appendFormat("%d",
4081 (int8_t) hdrBracketingSetting.exp_val.values[i]);
4082 tmp.append(",");
4083 }
4084 if (mParameters.isHDR1xFrameEnabled()
4085 && mParameters.isHDR1xExtraBufferNeeded()) {
4086 tmp.appendFormat("%d", 0);
4087 tmp.append(",");
4088 }
4089
4090 if( !tmp.isEmpty() &&
4091 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
4092 //Trim last comma
4093 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
4094 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
4095 }
4096
4097 LOGH("HDR config values %s",
4098 aeBracket.values);
4099 rc = mParameters.setHDRAEBracket(aeBracket);
4100 if ( NO_ERROR != rc ) {
4101 LOGE("cannot configure HDR bracketing");
4102 return rc;
4103 }
4104 LOGH("X rc = %d", rc);
4105 return rc;
4106 }
4107
4108 /*===========================================================================
4109 * FUNCTION : configureAEBracketing
4110 *
4111 * DESCRIPTION: configure AE Bracketing.
4112 *
4113 * PARAMETERS : none
4114 *
4115 * RETURN : int32_t type of status
4116 * NO_ERROR -- success
4117 * none-zero failure code
4118 *==========================================================================*/
configureAEBracketing()4119 int32_t QCamera2HardwareInterface::configureAEBracketing()
4120 {
4121 LOGH("E");
4122 int32_t rc = NO_ERROR;
4123
4124 rc = mParameters.setAEBracketing();
4125 if ( NO_ERROR != rc ) {
4126 LOGE("cannot configure AE bracketing");
4127 return rc;
4128 }
4129 LOGH("X rc = %d", rc);
4130 return rc;
4131 }
4132
4133 /*===========================================================================
4134 * FUNCTION : configureOptiZoom
4135 *
4136 * DESCRIPTION: configure Opti Zoom.
4137 *
4138 * PARAMETERS : none
4139 *
4140 * RETURN : int32_t type of status
4141 * NO_ERROR -- success
4142 * none-zero failure code
4143 *==========================================================================*/
configureOptiZoom()4144 int32_t QCamera2HardwareInterface::configureOptiZoom()
4145 {
4146 int32_t rc = NO_ERROR;
4147
4148 //store current zoom level.
4149 mZoomLevel = mParameters.getParmZoomLevel();
4150
4151 //set zoom level to 1x;
4152 mParameters.setAndCommitZoom(0);
4153
4154 mParameters.set3ALock(true);
4155 mIs3ALocked = true;
4156
4157 return rc;
4158 }
4159
4160 /*===========================================================================
4161 * FUNCTION : configureStillMore
4162 *
4163 * DESCRIPTION: configure StillMore.
4164 *
4165 * PARAMETERS : none
4166 *
4167 * RETURN : int32_t type of status
4168 * NO_ERROR -- success
4169 * none-zero failure code
4170 *==========================================================================*/
configureStillMore()4171 int32_t QCamera2HardwareInterface::configureStillMore()
4172 {
4173 int32_t rc = NO_ERROR;
4174 uint8_t burst_cnt = 0;
4175 cam_still_more_t stillmore_config;
4176 cam_still_more_t stillmore_cap;
4177
4178 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
4179 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4180 rc = mParameters.setToneMapMode(false, true);
4181 if (rc != NO_ERROR) {
4182 LOGW("Failed to disable tone map during StillMore");
4183 }
4184 }
4185
4186 /* Lock 3A */
4187 mParameters.set3ALock(true);
4188 mIs3ALocked = true;
4189
4190 /* Disable Tintless */
4191 mParameters.setTintless(false);
4192
4193 /* Initialize burst count from capability */
4194 stillmore_cap = mParameters.getStillMoreCapability();
4195 burst_cnt = stillmore_cap.max_burst_count;
4196
4197 /* Reconfigure burst count from dynamic scene data */
4198 cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
4199 if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
4200 dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
4201 burst_cnt = dynamic_img_data.input_count;
4202 }
4203
4204 /* Reconfigure burst count in the case of liveshot */
4205 if (mParameters.isSeeMoreEnabled()) {
4206 burst_cnt = 1;
4207 }
4208
4209 /* Reconfigure burst count from user input */
4210 char prop[PROPERTY_VALUE_MAX];
4211 property_get("persist.camera.imglib.stillmore", prop, "0");
4212 uint8_t burst_setprop = (uint32_t)atoi(prop);
4213 if (burst_setprop != 0) {
4214 if ((burst_setprop < stillmore_cap.min_burst_count) ||
4215 (burst_setprop > stillmore_cap.max_burst_count)) {
4216 burst_cnt = stillmore_cap.max_burst_count;
4217 } else {
4218 burst_cnt = burst_setprop;
4219 }
4220 }
4221
4222 memset(&stillmore_config, 0, sizeof(cam_still_more_t));
4223 stillmore_config.burst_count = burst_cnt;
4224 mParameters.setStillMoreSettings(stillmore_config);
4225
4226 LOGH("Stillmore burst %d", burst_cnt);
4227
4228 return rc;
4229 }
4230
4231 /*===========================================================================
4232 * FUNCTION : stopAdvancedCapture
4233 *
4234 * DESCRIPTION: stops advanced capture based on capture type
4235 *
4236 * PARAMETERS :
4237 * @pChannel : channel.
4238 *
4239 * RETURN : int32_t type of status
4240 * NO_ERROR -- success
4241 * none-zero failure code
4242 *==========================================================================*/
stopAdvancedCapture(QCameraPicChannel * pChannel)4243 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
4244 QCameraPicChannel *pChannel)
4245 {
4246 LOGH("stop bracketig");
4247 int32_t rc = NO_ERROR;
4248
4249 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4250 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4251 } else if (mParameters.isChromaFlashEnabled()
4252 || (mFlashNeeded && !mLongshotEnabled)
4253 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4254 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4255 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
4256 } else if(mParameters.isHDREnabled()
4257 || mParameters.isAEBracketEnabled()) {
4258 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4259 } else if (mParameters.isOptiZoomEnabled()) {
4260 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
4261 } else if (mParameters.isStillMoreEnabled()) {
4262 LOGH("stopAdvancedCapture not needed for StillMore");
4263 } else {
4264 LOGH("No Advanced Capture feature enabled!");
4265 rc = BAD_VALUE;
4266 }
4267 return rc;
4268 }
4269
4270 /*===========================================================================
4271 * FUNCTION : startAdvancedCapture
4272 *
4273 * DESCRIPTION: starts advanced capture based on capture type
4274 *
4275 * PARAMETERS :
4276 * @pChannel : channel.
4277 *
4278 * RETURN : int32_t type of status
4279 * NO_ERROR -- success
4280 * none-zero failure code
4281 *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)4282 int32_t QCamera2HardwareInterface::startAdvancedCapture(
4283 QCameraPicChannel *pChannel)
4284 {
4285 LOGH("Start bracketing");
4286 int32_t rc = NO_ERROR;
4287
4288 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4289 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4290 } else if (mParameters.isOptiZoomEnabled()) {
4291 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
4292 } else if (mParameters.isStillMoreEnabled()) {
4293 LOGH("startAdvancedCapture not needed for StillMore");
4294 } else if (mParameters.isHDREnabled()
4295 || mParameters.isAEBracketEnabled()) {
4296 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4297 } else if (mParameters.isChromaFlashEnabled()
4298 || (mFlashNeeded && !mLongshotEnabled)
4299 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4300 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4301 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
4302 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
4303 } else {
4304 LOGE("No Advanced Capture feature enabled!");
4305 rc = BAD_VALUE;
4306 }
4307 return rc;
4308 }
4309
4310 /*===========================================================================
4311 * FUNCTION : preTakePicture
4312 *
4313 * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
4314 *
4315 * PARAMETERS : none
4316 *
4317 * RETURN : int32_t type of status
4318 * NO_ERROR -- success
4319 * none-zero failure code
4320 *==========================================================================*/
preTakePicture()4321 int QCamera2HardwareInterface::preTakePicture()
4322 {
4323 int32_t rc = NO_ERROR;
4324 LOGH("E");
4325 if (mParameters.getRecordingHintValue() == true) {
4326
4327 // Give HWI control to restart preview only in single camera mode.
4328 // In dual-cam mode, this control belongs to muxer.
4329 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4330 LOGH("restart preview if rec hint is true and preview is running");
4331 stopPreview();
4332 mParameters.updateRecordingHintValue(FALSE);
4333 // start preview again
4334 rc = preparePreview();
4335 if (rc == NO_ERROR) {
4336 rc = startPreview();
4337 if (rc != NO_ERROR) {
4338 unpreparePreview();
4339 }
4340 }
4341 }
4342 else
4343 {
4344 // For dual cam mode, update the flag mPreviewRestartNeeded to true
4345 // Restart control will be handled by muxer.
4346 mPreviewRestartNeeded = true;
4347 }
4348 }
4349
4350 LOGH("X rc = %d", rc);
4351 return rc;
4352 }
4353
4354 /*===========================================================================
4355 * FUNCTION : takePicture
4356 *
4357 * DESCRIPTION: take picture impl
4358 *
4359 * PARAMETERS : none
4360 *
4361 * RETURN : int32_t type of status
4362 * NO_ERROR -- success
4363 * none-zero failure code
4364 *==========================================================================*/
takePicture()4365 int QCamera2HardwareInterface::takePicture()
4366 {
4367 int rc = NO_ERROR;
4368
4369 // Get total number for snapshots (retro + regular)
4370 uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4371 // Get number of retro-active snapshots
4372 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
4373 LOGH("E");
4374
4375 //Set rotation value from user settings as Jpeg rotation
4376 //to configure back-end modules.
4377 mParameters.setJpegRotation(mParameters.getRotation());
4378
4379 // Check if retro-active snapshots are not enabled
4380 if (!isRetroPicture() || !mParameters.isZSLMode()) {
4381 numRetroSnapshots = 0;
4382 LOGH("Reset retro snaphot count to zero");
4383 }
4384
4385 //Do special configure for advanced capture modes.
4386 rc = configureAdvancedCapture();
4387 if (rc != NO_ERROR) {
4388 LOGE("Unsupported capture call");
4389 return rc;
4390 }
4391
4392 if (mAdvancedCaptureConfigured) {
4393 numSnapshots = mParameters.getBurstCountForAdvancedCapture();
4394 }
4395 LOGI("snap count = %d zsl = %d advanced = %d",
4396 numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured);
4397
4398 if (mParameters.isZSLMode()) {
4399 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
4400 QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
4401 if (NULL != pPicChannel) {
4402
4403 if (mParameters.getofflineRAW()) {
4404 startRAWChannel(pPicChannel);
4405 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4406 if (pPicChannel == NULL) {
4407 LOGE("RAW Channel is NULL in Manual capture mode");
4408 stopRAWChannel();
4409 return UNKNOWN_ERROR;
4410 }
4411 }
4412
4413 rc = configureOnlineRotation(*pPicChannel);
4414 if (rc != NO_ERROR) {
4415 LOGE("online rotation failed");
4416 return rc;
4417 }
4418
4419 // start postprocessor
4420 DeferWorkArgs args;
4421 memset(&args, 0, sizeof(DeferWorkArgs));
4422
4423 args.pprocArgs = pPicChannel;
4424
4425 // No need to wait for mInitPProcJob here, because it was
4426 // queued in startPreview, and will definitely be processed before
4427 // mReprocJob can begin.
4428 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4429 args);
4430 if (mReprocJob == 0) {
4431 LOGE("Failure: Unable to start pproc");
4432 return -ENOMEM;
4433 }
4434
4435 // Check if all preview buffers are mapped before creating
4436 // a jpeg session as preview stream buffers are queried during the same
4437 uint8_t numStreams = pChannel->getNumOfStreams();
4438 QCameraStream *pStream = NULL;
4439 QCameraStream *pPreviewStream = NULL;
4440 for (uint8_t i = 0 ; i < numStreams ; i++ ) {
4441 pStream = pChannel->getStreamByIndex(i);
4442 if (!pStream)
4443 continue;
4444 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
4445 pPreviewStream = pStream;
4446 break;
4447 }
4448 }
4449 if (pPreviewStream != NULL) {
4450 Mutex::Autolock l(mMapLock);
4451 QCameraMemory *pMemory = pStream->getStreamBufs();
4452 if (!pMemory) {
4453 LOGE("Error!! pMemory is NULL");
4454 return -ENOMEM;
4455 }
4456
4457 uint8_t waitCnt = 2;
4458 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
4459 LOGL(" Waiting for preview buffers to be mapped");
4460 mMapCond.waitRelative(
4461 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
4462 LOGL("Wait completed!!");
4463 waitCnt--;
4464 }
4465 // If all buffers are not mapped after retries, assert
4466 assert(pMemory->checkIfAllBuffersMapped());
4467 } else {
4468 assert(pPreviewStream);
4469 }
4470
4471 // Create JPEG session
4472 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
4473 args);
4474 if (mJpegJob == 0) {
4475 LOGE("Failed to queue CREATE_JPEG_SESSION");
4476 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4477 LOGE("Reprocess Deferred work was failed");
4478 }
4479 m_postprocessor.stop();
4480 return -ENOMEM;
4481 }
4482
4483 if (mAdvancedCaptureConfigured) {
4484 rc = startAdvancedCapture(pPicChannel);
4485 if (rc != NO_ERROR) {
4486 LOGE("cannot start zsl advanced capture");
4487 return rc;
4488 }
4489 }
4490 if (mLongshotEnabled && mPrepSnapRun) {
4491 mCameraHandle->ops->start_zsl_snapshot(
4492 mCameraHandle->camera_handle,
4493 pPicChannel->getMyHandle());
4494 }
4495 // If frame sync is ON and it is a SECONDARY camera,
4496 // we do not need to send the take picture command to interface
4497 // It will be handled along with PRIMARY camera takePicture request
4498 mm_camera_req_buf_t buf;
4499 memset(&buf, 0x0, sizeof(buf));
4500 if ((!mParameters.isAdvCamFeaturesEnabled() &&
4501 !mFlashNeeded &&
4502 !isLongshotEnabled() &&
4503 getRelatedCamSyncInfo()->is_frame_sync_enabled) &&
4504 (getRelatedCamSyncInfo()->sync_control ==
4505 CAM_SYNC_RELATED_SENSORS_ON)) {
4506 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
4507 buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
4508 buf.num_buf_requested = numSnapshots;
4509 rc = pPicChannel->takePicture(&buf);
4510 if (rc != NO_ERROR) {
4511 LOGE("FS_DBG cannot take ZSL picture, stop pproc");
4512 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4513 LOGE("Reprocess Deferred work failed");
4514 return UNKNOWN_ERROR;
4515 }
4516 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4517 LOGE("Jpeg Deferred work failed");
4518 return UNKNOWN_ERROR;
4519 }
4520 m_postprocessor.stop();
4521 return rc;
4522 }
4523 LOGI("PRIMARY camera: send frame sync takePicture!!");
4524 }
4525 } else {
4526 buf.type = MM_CAMERA_REQ_SUPER_BUF;
4527 buf.num_buf_requested = numSnapshots;
4528 buf.num_retro_buf_requested = numRetroSnapshots;
4529 rc = pPicChannel->takePicture(&buf);
4530 if (rc != NO_ERROR) {
4531 LOGE("cannot take ZSL picture, stop pproc");
4532 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4533 LOGE("Reprocess Deferred work failed");
4534 return UNKNOWN_ERROR;
4535 }
4536 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4537 LOGE("Jpeg Deferred work failed");
4538 return UNKNOWN_ERROR;
4539 }
4540 m_postprocessor.stop();
4541 return rc;
4542 }
4543 }
4544 } else {
4545 LOGE("ZSL channel is NULL");
4546 return UNKNOWN_ERROR;
4547 }
4548 } else {
4549
4550 // start snapshot
4551 if (mParameters.isJpegPictureFormat() ||
4552 mParameters.isNV16PictureFormat() ||
4553 mParameters.isNV21PictureFormat()) {
4554
4555 //STOP Preview for Non ZSL use case
4556 stopPreview();
4557
4558 //Config CAPTURE channels
4559 rc = declareSnapshotStreams();
4560 if (NO_ERROR != rc) {
4561 return rc;
4562 }
4563
4564 rc = addCaptureChannel();
4565 if ((rc == NO_ERROR) &&
4566 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
4567
4568 if (!mParameters.getofflineRAW()) {
4569 rc = configureOnlineRotation(
4570 *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
4571 if (rc != NO_ERROR) {
4572 LOGE("online rotation failed");
4573 delChannel(QCAMERA_CH_TYPE_CAPTURE);
4574 return rc;
4575 }
4576 }
4577
4578 DeferWorkArgs args;
4579 memset(&args, 0, sizeof(DeferWorkArgs));
4580
4581 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
4582
4583 // No need to wait for mInitPProcJob here, because it was
4584 // queued in startPreview, and will definitely be processed before
4585 // mReprocJob can begin.
4586 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4587 args);
4588 if (mReprocJob == 0) {
4589 LOGE("Failure: Unable to start pproc");
4590 return -ENOMEM;
4591 }
4592
4593 // Create JPEG session
4594 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
4595 args);
4596 if (mJpegJob == 0) {
4597 LOGE("Failed to queue CREATE_JPEG_SESSION");
4598 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4599 LOGE("Reprocess Deferred work was failed");
4600 }
4601 m_postprocessor.stop();
4602 return -ENOMEM;
4603 }
4604
4605 // start catpure channel
4606 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
4607 if (rc != NO_ERROR) {
4608 LOGE("cannot start capture channel");
4609 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4610 LOGE("Reprocess Deferred work failed");
4611 return UNKNOWN_ERROR;
4612 }
4613 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4614 LOGE("Jpeg Deferred work failed");
4615 return UNKNOWN_ERROR;
4616 }
4617 delChannel(QCAMERA_CH_TYPE_CAPTURE);
4618 return rc;
4619 }
4620
4621 QCameraPicChannel *pCapChannel =
4622 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
4623 if (NULL != pCapChannel) {
4624 if (mParameters.isUbiFocusEnabled() ||
4625 mParameters.isUbiRefocus() ||
4626 mParameters.isChromaFlashEnabled()) {
4627 rc = startAdvancedCapture(pCapChannel);
4628 if (rc != NO_ERROR) {
4629 LOGE("cannot start advanced capture");
4630 return rc;
4631 }
4632 }
4633 }
4634 if ( mLongshotEnabled ) {
4635 rc = longShot();
4636 if (NO_ERROR != rc) {
4637 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
4638 LOGE("Reprocess Deferred work failed");
4639 return UNKNOWN_ERROR;
4640 }
4641 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
4642 LOGE("Jpeg Deferred work failed");
4643 return UNKNOWN_ERROR;
4644 }
4645 delChannel(QCAMERA_CH_TYPE_CAPTURE);
4646 return rc;
4647 }
4648 }
4649 } else {
4650 LOGE("cannot add capture channel");
4651 delChannel(QCAMERA_CH_TYPE_CAPTURE);
4652 return rc;
4653 }
4654 } else {
4655 // Stop Preview before taking NZSL snapshot
4656 stopPreview();
4657
4658 rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
4659 if (NO_ERROR != rc) {
4660 LOGE("Raw dimension update failed %d", rc);
4661 return rc;
4662 }
4663
4664 rc = declareSnapshotStreams();
4665 if (NO_ERROR != rc) {
4666 LOGE("RAW stream info configuration failed %d", rc);
4667 return rc;
4668 }
4669
4670 rc = addChannel(QCAMERA_CH_TYPE_RAW);
4671 if (rc == NO_ERROR) {
4672 // start postprocessor
4673 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
4674 LOGE("Reprocess Deferred work failed");
4675 return UNKNOWN_ERROR;
4676 }
4677
4678 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
4679 if (rc != NO_ERROR) {
4680 LOGE("cannot start postprocessor");
4681 delChannel(QCAMERA_CH_TYPE_RAW);
4682 return rc;
4683 }
4684
4685 rc = startChannel(QCAMERA_CH_TYPE_RAW);
4686 if (rc != NO_ERROR) {
4687 LOGE("cannot start raw channel");
4688 m_postprocessor.stop();
4689 delChannel(QCAMERA_CH_TYPE_RAW);
4690 return rc;
4691 }
4692 } else {
4693 LOGE("cannot add raw channel");
4694 return rc;
4695 }
4696 }
4697 }
4698
4699 //When take picture, stop sending preview callbacks to APP
4700 m_stateMachine.setPreviewCallbackNeeded(false);
4701 LOGI("X rc = %d", rc);
4702 return rc;
4703 }
4704
4705 /*===========================================================================
4706 * FUNCTION : configureOnlineRotation
4707 *
4708 * DESCRIPTION: Configure backend with expected rotation for snapshot stream
4709 *
4710 * PARAMETERS :
4711 * @ch : Channel containing a snapshot stream
4712 *
4713 * RETURN : int32_t type of status
4714 * NO_ERROR -- success
4715 * none-zero failure code
4716 *==========================================================================*/
configureOnlineRotation(QCameraChannel & ch)4717 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
4718 {
4719 int rc = NO_ERROR;
4720 uint32_t streamId = 0;
4721 QCameraStream *pStream = NULL;
4722
4723 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
4724 QCameraStream *stream = ch.getStreamByIndex(i);
4725 if ((NULL != stream) &&
4726 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
4727 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
4728 pStream = stream;
4729 break;
4730 }
4731 }
4732
4733 if (NULL == pStream) {
4734 LOGE("No snapshot stream found!");
4735 return BAD_VALUE;
4736 }
4737
4738 streamId = pStream->getMyServerID();
4739 // Update online rotation configuration
4740 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
4741 mParameters.getDeviceRotation());
4742 if (rc != NO_ERROR) {
4743 LOGE("addOnlineRotation failed %d", rc);
4744 return rc;
4745 }
4746
4747 return rc;
4748 }
4749
4750 /*===========================================================================
4751 * FUNCTION : declareSnapshotStreams
4752 *
4753 * DESCRIPTION: Configure backend with expected snapshot streams
4754 *
4755 * PARAMETERS : none
4756 *
4757 * RETURN : int32_t type of status
4758 * NO_ERROR -- success
4759 * none-zero failure code
4760 *==========================================================================*/
declareSnapshotStreams()4761 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
4762 {
4763 int rc = NO_ERROR;
4764
4765 // Update stream info configuration
4766 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
4767 if (rc != NO_ERROR) {
4768 LOGE("setStreamConfigure failed %d", rc);
4769 return rc;
4770 }
4771
4772 return rc;
4773 }
4774
4775 /*===========================================================================
4776 * FUNCTION : longShot
4777 *
4778 * DESCRIPTION: Queue one more ZSL frame
4779 * in the longshot pipe.
4780 *
4781 * PARAMETERS : none
4782 *
4783 * RETURN : int32_t type of status
4784 * NO_ERROR -- success
4785 * none-zero failure code
4786 *==========================================================================*/
longShot()4787 int32_t QCamera2HardwareInterface::longShot()
4788 {
4789 int32_t rc = NO_ERROR;
4790 uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4791 QCameraPicChannel *pChannel = NULL;
4792
4793 if (mParameters.isZSLMode()) {
4794 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
4795 } else {
4796 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
4797 }
4798
4799 if (NULL != pChannel) {
4800 mm_camera_req_buf_t buf;
4801 memset(&buf, 0x0, sizeof(buf));
4802 buf.type = MM_CAMERA_REQ_SUPER_BUF;
4803 buf.num_buf_requested = numSnapshots;
4804 rc = pChannel->takePicture(&buf);
4805 } else {
4806 LOGE("Capture channel not initialized!");
4807 rc = NO_INIT;
4808 goto end;
4809 }
4810
4811 end:
4812 return rc;
4813 }
4814
4815 /*===========================================================================
4816 * FUNCTION : stopCaptureChannel
4817 *
4818 * DESCRIPTION: Stops capture channel
4819 *
4820 * PARAMETERS :
4821 * @destroy : Set to true to stop and delete camera channel.
4822 * Set to false to only stop capture channel.
4823 *
4824 * RETURN : int32_t type of status
4825 * NO_ERROR -- success
4826 * none-zero failure code
4827 *==========================================================================*/
stopCaptureChannel(bool destroy)4828 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
4829 {
4830 int rc = NO_ERROR;
4831 if (mParameters.isJpegPictureFormat() ||
4832 mParameters.isNV16PictureFormat() ||
4833 mParameters.isNV21PictureFormat()) {
4834 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
4835 if (destroy && (NO_ERROR == rc)) {
4836 // Destroy camera channel but dont release context
4837 waitDeferredWork(mJpegJob);
4838 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
4839 }
4840 }
4841
4842 return rc;
4843 }
4844
4845 /*===========================================================================
4846 * FUNCTION : cancelPicture
4847 *
4848 * DESCRIPTION: cancel picture impl
4849 *
4850 * PARAMETERS : none
4851 *
4852 * RETURN : int32_t type of status
4853 * NO_ERROR -- success
4854 * none-zero failure code
4855 *==========================================================================*/
cancelPicture()4856 int QCamera2HardwareInterface::cancelPicture()
4857 {
4858 waitDeferredWork(mReprocJob);
4859 waitDeferredWork(mJpegJob);
4860
4861 //stop post processor
4862 m_postprocessor.stop();
4863
4864 unconfigureAdvancedCapture();
4865 LOGH("Enable display frames again");
4866 setDisplaySkip(FALSE);
4867
4868 if (!mLongshotEnabled) {
4869 m_perfLock.lock_rel();
4870 }
4871
4872 if (mParameters.isZSLMode()) {
4873 QCameraPicChannel *pPicChannel = NULL;
4874 if (mParameters.getofflineRAW()) {
4875 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4876 } else {
4877 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
4878 }
4879 if (NULL != pPicChannel) {
4880 pPicChannel->cancelPicture();
4881 stopRAWChannel();
4882 stopAdvancedCapture(pPicChannel);
4883 }
4884 } else {
4885
4886 // normal capture case
4887 if (mParameters.isJpegPictureFormat() ||
4888 mParameters.isNV16PictureFormat() ||
4889 mParameters.isNV21PictureFormat()) {
4890 stopChannel(QCAMERA_CH_TYPE_CAPTURE);
4891 delChannel(QCAMERA_CH_TYPE_CAPTURE);
4892 } else {
4893 stopChannel(QCAMERA_CH_TYPE_RAW);
4894 delChannel(QCAMERA_CH_TYPE_RAW);
4895 }
4896 }
4897
4898 return NO_ERROR;
4899 }
4900
4901 /*===========================================================================
4902 * FUNCTION : captureDone
4903 *
4904 * DESCRIPTION: Function called when the capture is completed before encoding
4905 *
4906 * PARAMETERS : none
4907 *
4908 * RETURN : none
4909 *==========================================================================*/
captureDone()4910 void QCamera2HardwareInterface::captureDone()
4911 {
4912 qcamera_sm_internal_evt_payload_t *payload =
4913 (qcamera_sm_internal_evt_payload_t *)
4914 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
4915 if (NULL != payload) {
4916 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
4917 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
4918 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
4919 if (rc != NO_ERROR) {
4920 LOGE("processEvt ZSL capture done failed");
4921 free(payload);
4922 payload = NULL;
4923 }
4924 } else {
4925 LOGE("No memory for ZSL capture done event");
4926 }
4927 }
4928
4929 /*===========================================================================
4930 * FUNCTION : Live_Snapshot_thread
4931 *
4932 * DESCRIPTION: Seperate thread for taking live snapshot during recording
4933 *
4934 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
4935 *
4936 * RETURN : none
4937 *==========================================================================*/
Live_Snapshot_thread(void * data)4938 void* Live_Snapshot_thread (void* data)
4939 {
4940
4941 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
4942 if (!hw) {
4943 LOGE("take_picture_thread: NULL camera device");
4944 return (void *)BAD_VALUE;
4945 }
4946 hw->takeLiveSnapshot_internal();
4947 return (void* )NULL;
4948 }
4949
4950 /*===========================================================================
4951 * FUNCTION : Int_Pic_thread
4952 *
4953 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
4954 *
4955 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
4956 *
4957 * RETURN : none
4958 *==========================================================================*/
Int_Pic_thread(void * data)4959 void* Int_Pic_thread (void* data)
4960 {
4961 int rc = NO_ERROR;
4962
4963 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
4964
4965 if (!hw) {
4966 LOGE("take_picture_thread: NULL camera device");
4967 return (void *)BAD_VALUE;
4968 }
4969
4970 bool JpegMemOpt = false;
4971 char raw_format[PROPERTY_VALUE_MAX];
4972
4973 memset(raw_format, 0, sizeof(raw_format));
4974
4975 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
4976 if (rc == NO_ERROR) {
4977 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
4978 } else {
4979 //Snapshot attempt not successful, we need to do cleanup here
4980 hw->clearIntPendingEvents();
4981 }
4982
4983 return (void* )NULL;
4984 }
4985
4986 /*===========================================================================
4987 * FUNCTION : takeLiveSnapshot
4988 *
4989 * DESCRIPTION: take live snapshot during recording
4990 *
4991 * PARAMETERS : none
4992 *
4993 * RETURN : int32_t type of status
4994 * NO_ERROR -- success
4995 * none-zero failure code
4996 *==========================================================================*/
takeLiveSnapshot()4997 int QCamera2HardwareInterface::takeLiveSnapshot()
4998 {
4999 int rc = NO_ERROR;
5000 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5001 if (!rc) {
5002 pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
5003 }
5004 return rc;
5005 }
5006
5007 /*===========================================================================
5008 * FUNCTION : takePictureInternal
5009 *
5010 * DESCRIPTION: take snapshot triggered by backend
5011 *
5012 * PARAMETERS : none
5013 *
5014 * RETURN : int32_t type of status
5015 * NO_ERROR -- success
5016 * none-zero failure code
5017 *==========================================================================*/
takePictureInternal()5018 int QCamera2HardwareInterface::takePictureInternal()
5019 {
5020 int rc = NO_ERROR;
5021 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
5022 if (!rc) {
5023 pthread_setname_np(mIntPicThread, "CAM_IntPic");
5024 }
5025 return rc;
5026 }
5027
5028 /*===========================================================================
5029 * FUNCTION : checkIntPicPending
5030 *
5031 * DESCRIPTION: timed wait for jpeg completion event, and send
5032 * back completion event to backend
5033 *
5034 * PARAMETERS : none
5035 *
5036 * RETURN : none
5037 *==========================================================================*/
checkIntPicPending(bool JpegMemOpt,char * raw_format)5038 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
5039 {
5040 bool bSendToBackend = true;
5041 cam_int_evt_params_t params;
5042 int rc = NO_ERROR;
5043
5044 struct timespec ts;
5045 struct timeval tp;
5046 gettimeofday(&tp, NULL);
5047 ts.tv_sec = tp.tv_sec + 5;
5048 ts.tv_nsec = tp.tv_usec * 1000;
5049
5050 if (true == m_bIntJpegEvtPending ||
5051 (true == m_bIntRawEvtPending)) {
5052 //Waiting in HAL for snapshot taken notification
5053 pthread_mutex_lock(&m_int_lock);
5054 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
5055 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
5056 //Hit a timeout, or some spurious activity
5057 bSendToBackend = false;
5058 }
5059
5060 if (true == m_bIntJpegEvtPending) {
5061 params.event_type = 0;
5062 mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
5063 } else if (true == m_bIntRawEvtPending) {
5064 params.event_type = 1;
5065 mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
5066 }
5067 pthread_mutex_unlock(&m_int_lock);
5068
5069 if (true == m_bIntJpegEvtPending) {
5070 //Attempting to restart preview after taking JPEG snapshot
5071 lockAPI();
5072 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5073 unlockAPI();
5074 m_postprocessor.setJpegMemOpt(JpegMemOpt);
5075 } else if (true == m_bIntRawEvtPending) {
5076 //Attempting to restart preview after taking RAW snapshot
5077 stopChannel(QCAMERA_CH_TYPE_RAW);
5078 delChannel(QCAMERA_CH_TYPE_RAW);
5079 //restoring the old raw format
5080 property_set("persist.camera.raw.format", raw_format);
5081 }
5082
5083 if (true == bSendToBackend) {
5084 //send event back to server with the file path
5085 params.dim = m_postprocessor.m_dst_dim;
5086 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
5087 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
5088 params.size = mBackendFileSize;
5089 rc = mParameters.setIntEvent(params);
5090 }
5091
5092 clearIntPendingEvents();
5093 }
5094
5095 return;
5096 }
5097
5098 /*===========================================================================
5099 * FUNCTION : takeBackendPic_internal
5100 *
5101 * DESCRIPTION: take snapshot triggered by backend
5102 *
5103 * PARAMETERS : none
5104 *
5105 * RETURN : int32_t type of status
5106 * NO_ERROR -- success
5107 * none-zero failure code
5108 *==========================================================================*/
takeBackendPic_internal(bool * JpegMemOpt,char * raw_format)5109 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
5110 {
5111 int rc = NO_ERROR;
5112 qcamera_api_result_t apiResult;
5113
5114 lockAPI();
5115 //Set rotation value from user settings as Jpeg rotation
5116 //to configure back-end modules.
5117 mParameters.setJpegRotation(mParameters.getRotation());
5118
5119 setRetroPicture(0);
5120 /* Prepare snapshot in case LED needs to be flashed */
5121 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
5122 // Start Preparing for normal Frames
5123 LOGH("Start Prepare Snapshot");
5124 /* Prepare snapshot in case LED needs to be flashed */
5125 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
5126 if (rc == NO_ERROR) {
5127 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
5128 rc = apiResult.status;
5129 }
5130 LOGH("Prep Snapshot done rc = %d", rc);
5131 mPrepSnapRun = true;
5132 }
5133 unlockAPI();
5134
5135 if (true == m_bIntJpegEvtPending) {
5136 //Attempting to take JPEG snapshot
5137 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5138 LOGE("Init PProc Deferred work failed");
5139 return UNKNOWN_ERROR;
5140 }
5141 *JpegMemOpt = m_postprocessor.getJpegMemOpt();
5142 m_postprocessor.setJpegMemOpt(false);
5143
5144 /* capture */
5145 lockAPI();
5146 LOGH("Capturing internal snapshot");
5147 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
5148 if (rc == NO_ERROR) {
5149 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
5150 rc = apiResult.status;
5151 }
5152 unlockAPI();
5153 } else if (true == m_bIntRawEvtPending) {
5154 //Attempting to take RAW snapshot
5155 (void)JpegMemOpt;
5156 stopPreview();
5157
5158 //getting the existing raw format type
5159 property_get("persist.camera.raw.format", raw_format, "17");
5160 //setting it to a default know value for this task
5161 property_set("persist.camera.raw.format", "18");
5162
5163 rc = addChannel(QCAMERA_CH_TYPE_RAW);
5164 if (rc == NO_ERROR) {
5165 // start postprocessor
5166 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5167 LOGE("Init PProc Deferred work failed");
5168 return UNKNOWN_ERROR;
5169 }
5170 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5171 if (rc != NO_ERROR) {
5172 LOGE("cannot start postprocessor");
5173 delChannel(QCAMERA_CH_TYPE_RAW);
5174 return rc;
5175 }
5176
5177 rc = startChannel(QCAMERA_CH_TYPE_RAW);
5178 if (rc != NO_ERROR) {
5179 LOGE("cannot start raw channel");
5180 m_postprocessor.stop();
5181 delChannel(QCAMERA_CH_TYPE_RAW);
5182 return rc;
5183 }
5184 } else {
5185 LOGE("cannot add raw channel");
5186 return rc;
5187 }
5188 }
5189
5190 return rc;
5191 }
5192
5193 /*===========================================================================
5194 * FUNCTION : clearIntPendingEvents
5195 *
5196 * DESCRIPTION: clear internal pending events pertaining to backend
5197 * snapshot requests
5198 *
5199 * PARAMETERS : none
5200 *
5201 * RETURN : int32_t type of status
5202 * NO_ERROR -- success
5203 * none-zero failure code
5204 *==========================================================================*/
clearIntPendingEvents()5205 void QCamera2HardwareInterface::clearIntPendingEvents()
5206 {
5207 int rc = NO_ERROR;
5208
5209 if (true == m_bIntRawEvtPending) {
5210 preparePreview();
5211 startPreview();
5212 }
5213 if (true == m_bIntJpegEvtPending) {
5214 if (false == mParameters.isZSLMode()) {
5215 lockAPI();
5216 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
5217 unlockAPI();
5218 }
5219 }
5220
5221 pthread_mutex_lock(&m_int_lock);
5222 if (true == m_bIntJpegEvtPending) {
5223 m_bIntJpegEvtPending = false;
5224 } else if (true == m_bIntRawEvtPending) {
5225 m_bIntRawEvtPending = false;
5226 }
5227 pthread_mutex_unlock(&m_int_lock);
5228 return;
5229 }
5230
5231 /*===========================================================================
5232 * FUNCTION : takeLiveSnapshot_internal
5233 *
5234 * DESCRIPTION: take live snapshot during recording
5235 *
5236 * PARAMETERS : none
5237 *
5238 * RETURN : int32_t type of status
5239 * NO_ERROR -- success
5240 * none-zero failure code
5241 *==========================================================================*/
takeLiveSnapshot_internal()5242 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
5243 {
5244 int rc = NO_ERROR;
5245
5246 QCameraChannel *pChannel = NULL;
5247
5248 //Set rotation value from user settings as Jpeg rotation
5249 //to configure back-end modules.
5250 mParameters.setJpegRotation(mParameters.getRotation());
5251
5252 // Configure advanced capture
5253 rc = configureAdvancedCapture();
5254 if (rc != NO_ERROR) {
5255 LOGE("Unsupported capture call");
5256 goto end;
5257 }
5258
5259 if (isLowPowerMode()) {
5260 pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
5261 } else {
5262 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5263 }
5264
5265 if (NULL == pChannel) {
5266 LOGE("Snapshot/Video channel not initialized");
5267 rc = NO_INIT;
5268 goto end;
5269 }
5270
5271 DeferWorkArgs args;
5272 memset(&args, 0, sizeof(DeferWorkArgs));
5273
5274 args.pprocArgs = pChannel;
5275
5276 // No need to wait for mInitPProcJob here, because it was
5277 // queued in startPreview, and will definitely be processed before
5278 // mReprocJob can begin.
5279 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5280 args);
5281 if (mReprocJob == 0) {
5282 LOGE("Failed to queue CMD_DEF_PPROC_START");
5283 rc = -ENOMEM;
5284 goto end;
5285 }
5286
5287 // Create JPEG session
5288 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5289 args);
5290 if (mJpegJob == 0) {
5291 LOGE("Failed to queue CREATE_JPEG_SESSION");
5292 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5293 LOGE("Reprocess Deferred work was failed");
5294 }
5295 m_postprocessor.stop();
5296 rc = -ENOMEM;
5297 goto end;
5298 }
5299
5300 if (isLowPowerMode()) {
5301 mm_camera_req_buf_t buf;
5302 memset(&buf, 0x0, sizeof(buf));
5303 buf.type = MM_CAMERA_REQ_SUPER_BUF;
5304 buf.num_buf_requested = 1;
5305 rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
5306 goto end;
5307 }
5308
5309 //Disable reprocess for 4K liveshot case
5310 if (!mParameters.is4k2kVideoResolution()) {
5311 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
5312 if (rc != NO_ERROR) {
5313 LOGE("online rotation failed");
5314 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5315 LOGE("Reprocess Deferred work was failed");
5316 }
5317 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5318 LOGE("Jpeg Deferred work was failed");
5319 }
5320 m_postprocessor.stop();
5321 return rc;
5322 }
5323 }
5324
5325 if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
5326 QCameraStream *pStream = NULL;
5327 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5328 pStream = pChannel->getStreamByIndex(i);
5329 if ((NULL != pStream) &&
5330 (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
5331 break;
5332 }
5333 }
5334 if (pStream != NULL) {
5335 LOGD("REQUEST_FRAMES event for TNR snapshot");
5336 cam_stream_parm_buffer_t param;
5337 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
5338 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5339 param.frameRequest.enableStream = 1;
5340 rc = pStream->setParameter(param);
5341 if (rc != NO_ERROR) {
5342 LOGE("Stream Event REQUEST_FRAMES failed");
5343 }
5344 goto end;
5345 }
5346 }
5347
5348 // start snapshot channel
5349 if ((rc == NO_ERROR) && (NULL != pChannel)) {
5350 // Do not link metadata stream for 4K2k resolution
5351 // as CPP processing would be done on snapshot stream and not
5352 // reprocess stream
5353 if (!mParameters.is4k2kVideoResolution()) {
5354 // Find and try to link a metadata stream from preview channel
5355 QCameraChannel *pMetaChannel = NULL;
5356 QCameraStream *pMetaStream = NULL;
5357 QCameraStream *pPreviewStream = NULL;
5358
5359 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
5360 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5361 uint32_t streamNum = pMetaChannel->getNumOfStreams();
5362 QCameraStream *pStream = NULL;
5363 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
5364 pStream = pMetaChannel->getStreamByIndex(i);
5365 if (NULL != pStream) {
5366 if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
5367 pMetaStream = pStream;
5368 } else if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5369 pPreviewStream = pStream;
5370 }
5371 }
5372 }
5373 }
5374
5375 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
5376 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
5377 if (NO_ERROR != rc) {
5378 LOGE("Metadata stream link failed %d", rc);
5379 }
5380 }
5381 if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
5382 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
5383 if (NO_ERROR != rc) {
5384 LOGE("Preview stream link failed %d", rc);
5385 }
5386 }
5387 }
5388 rc = pChannel->start();
5389 }
5390
5391 end:
5392 if (rc != NO_ERROR) {
5393 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
5394 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
5395 }
5396 return rc;
5397 }
5398
5399 /*===========================================================================
5400 * FUNCTION : cancelLiveSnapshot
5401 *
5402 * DESCRIPTION: cancel current live snapshot request
5403 *
5404 * PARAMETERS : none
5405 *
5406 * RETURN : int32_t type of status
5407 * NO_ERROR -- success
5408 * none-zero failure code
5409 *==========================================================================*/
cancelLiveSnapshot()5410 int QCamera2HardwareInterface::cancelLiveSnapshot()
5411 {
5412 int rc = NO_ERROR;
5413
5414 unconfigureAdvancedCapture();
5415 LOGH("Enable display frames again");
5416 setDisplaySkip(FALSE);
5417
5418 if (!mLongshotEnabled) {
5419 m_perfLock.lock_rel();
5420 }
5421
5422 if (mLiveSnapshotThread != 0) {
5423 pthread_join(mLiveSnapshotThread,NULL);
5424 mLiveSnapshotThread = 0;
5425 }
5426
5427 //stop post processor
5428 m_postprocessor.stop();
5429
5430 // stop snapshot channel
5431 if (!mParameters.isTNRSnapshotEnabled()) {
5432 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
5433 } else {
5434 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5435 if (NULL != pChannel) {
5436 QCameraStream *pStream = NULL;
5437 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5438 pStream = pChannel->getStreamByIndex(i);
5439 if ((NULL != pStream) &&
5440 (CAM_STREAM_TYPE_SNAPSHOT ==
5441 pStream->getMyType())) {
5442 break;
5443 }
5444 }
5445 if (pStream != NULL) {
5446 LOGD("REQUEST_FRAMES event for TNR snapshot");
5447 cam_stream_parm_buffer_t param;
5448 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
5449 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5450 param.frameRequest.enableStream = 0;
5451 rc = pStream->setParameter(param);
5452 if (rc != NO_ERROR) {
5453 LOGE("Stream Event REQUEST_FRAMES failed");
5454 }
5455 }
5456 }
5457 }
5458
5459 return rc;
5460 }
5461
5462 /*===========================================================================
5463 * FUNCTION : putParameters
5464 *
5465 * DESCRIPTION: put parameters string impl
5466 *
5467 * PARAMETERS :
5468 * @parms : parameters string to be released
5469 *
5470 * RETURN : int32_t type of status
5471 * NO_ERROR -- success
5472 * none-zero failure code
5473 *==========================================================================*/
putParameters(char * parms)5474 int QCamera2HardwareInterface::putParameters(char *parms)
5475 {
5476 free(parms);
5477 return NO_ERROR;
5478 }
5479
5480 /*===========================================================================
5481 * FUNCTION : sendCommand
5482 *
5483 * DESCRIPTION: send command impl
5484 *
5485 * PARAMETERS :
5486 * @command : command to be executed
5487 * @arg1 : optional argument 1
5488 * @arg2 : optional argument 2
5489 *
5490 * RETURN : int32_t type of status
5491 * NO_ERROR -- success
5492 * none-zero failure code
5493 *==========================================================================*/
sendCommand(int32_t command,__unused int32_t & arg1,__unused int32_t & arg2)5494 int QCamera2HardwareInterface::sendCommand(int32_t command,
5495 __unused int32_t &arg1, __unused int32_t &arg2)
5496 {
5497 int rc = NO_ERROR;
5498
5499 switch (command) {
5500 #ifndef VANILLA_HAL
5501 case CAMERA_CMD_LONGSHOT_ON:
5502 m_perfLock.lock_acq();
5503 arg1 = arg2 = 0;
5504 // Longshot can only be enabled when image capture
5505 // is not active.
5506 if ( !m_stateMachine.isCaptureRunning() ) {
5507 LOGI("Longshot Enabled");
5508 mLongshotEnabled = true;
5509 rc = mParameters.setLongshotEnable(mLongshotEnabled);
5510
5511 // Due to recent buffer count optimizations
5512 // ZSL might run with considerably less buffers
5513 // when not in longshot mode. Preview needs to
5514 // restart in this case.
5515 if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
5516 QCameraChannel *pChannel = NULL;
5517 QCameraStream *pSnapStream = NULL;
5518 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
5519 if (NULL != pChannel) {
5520 QCameraStream *pStream = NULL;
5521 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
5522 pStream = pChannel->getStreamByIndex(i);
5523 if (pStream != NULL) {
5524 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
5525 pSnapStream = pStream;
5526 break;
5527 }
5528 }
5529 }
5530 if (NULL != pSnapStream) {
5531 uint8_t required = 0;
5532 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
5533 if (pSnapStream->getBufferCount() < required) {
5534 // We restart here, to reset the FPS and no
5535 // of buffers as per the requirement of longshot usecase.
5536 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
5537 if (getRelatedCamSyncInfo()->sync_control ==
5538 CAM_SYNC_RELATED_SENSORS_ON) {
5539 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
5540 }
5541 }
5542 }
5543 }
5544 }
5545 //
5546 mPrepSnapRun = false;
5547 mCACDoneReceived = FALSE;
5548 } else {
5549 rc = NO_INIT;
5550 }
5551 break;
5552 case CAMERA_CMD_LONGSHOT_OFF:
5553 m_perfLock.lock_rel();
5554 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
5555 cancelPicture();
5556 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5557 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
5558 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
5559 mCameraHandle->ops->stop_zsl_snapshot(
5560 mCameraHandle->camera_handle,
5561 pZSLChannel->getMyHandle());
5562 }
5563 }
5564 mPrepSnapRun = false;
5565 LOGI("Longshot Disabled");
5566 mLongshotEnabled = false;
5567 rc = mParameters.setLongshotEnable(mLongshotEnabled);
5568 mCACDoneReceived = FALSE;
5569 break;
5570 case CAMERA_CMD_HISTOGRAM_ON:
5571 case CAMERA_CMD_HISTOGRAM_OFF:
5572 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
5573 LOGH("Histogram -> %s",
5574 mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
5575 break;
5576 #endif
5577 case CAMERA_CMD_START_FACE_DETECTION:
5578 case CAMERA_CMD_STOP_FACE_DETECTION:
5579 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
5580 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
5581 LOGH("FaceDetection -> %s",
5582 mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
5583 break;
5584 #ifndef VANILLA_HAL
5585 case CAMERA_CMD_HISTOGRAM_SEND_DATA:
5586 #endif
5587 default:
5588 rc = NO_ERROR;
5589 break;
5590 }
5591 return rc;
5592 }
5593
5594 /*===========================================================================
5595 * FUNCTION : registerFaceImage
5596 *
5597 * DESCRIPTION: register face image impl
5598 *
5599 * PARAMETERS :
5600 * @img_ptr : ptr to image buffer
5601 * @config : ptr to config struct about input image info
5602 * @faceID : [OUT] face ID to uniquely identifiy the registered face image
5603 *
5604 * RETURN : int32_t type of status
5605 * NO_ERROR -- success
5606 * none-zero failure code
5607 *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)5608 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
5609 cam_pp_offline_src_config_t *config,
5610 int32_t &faceID)
5611 {
5612 int rc = NO_ERROR;
5613 faceID = -1;
5614
5615 if (img_ptr == NULL || config == NULL) {
5616 LOGE("img_ptr or config is NULL");
5617 return BAD_VALUE;
5618 }
5619
5620 // allocate ion memory for source image
5621 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
5622 if (imgBuf == NULL) {
5623 LOGE("Unable to new heap memory obj for image buf");
5624 return NO_MEMORY;
5625 }
5626
5627 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE);
5628 if (rc < 0) {
5629 LOGE("Unable to allocate heap memory for image buf");
5630 delete imgBuf;
5631 return NO_MEMORY;
5632 }
5633
5634 void *pBufPtr = imgBuf->getPtr(0);
5635 if (pBufPtr == NULL) {
5636 LOGE("image buf is NULL");
5637 imgBuf->deallocate();
5638 delete imgBuf;
5639 return NO_MEMORY;
5640 }
5641 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
5642
5643 cam_pp_feature_config_t pp_feature;
5644 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
5645 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
5646 QCameraReprocessChannel *pChannel =
5647 addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
5648
5649 if (pChannel == NULL) {
5650 LOGE("fail to add offline reprocess channel");
5651 imgBuf->deallocate();
5652 delete imgBuf;
5653 return UNKNOWN_ERROR;
5654 }
5655
5656 rc = pChannel->start();
5657 if (rc != NO_ERROR) {
5658 LOGE("Cannot start reprocess channel");
5659 imgBuf->deallocate();
5660 delete imgBuf;
5661 delete pChannel;
5662 return rc;
5663 }
5664
5665 ssize_t bufSize = imgBuf->getSize(0);
5666 if (BAD_INDEX != bufSize) {
5667 rc = pChannel->doReprocess(imgBuf->getFd(0), (size_t)bufSize, faceID);
5668 } else {
5669 LOGE("Failed to retrieve buffer size (bad index)");
5670 return UNKNOWN_ERROR;
5671 }
5672
5673 // done with register face image, free imgbuf and delete reprocess channel
5674 imgBuf->deallocate();
5675 delete imgBuf;
5676 imgBuf = NULL;
5677 pChannel->stop();
5678 delete pChannel;
5679 pChannel = NULL;
5680
5681 return rc;
5682 }
5683
5684 /*===========================================================================
5685 * FUNCTION : release
5686 *
5687 * DESCRIPTION: release camera resource impl
5688 *
5689 * PARAMETERS : none
5690 *
5691 * RETURN : int32_t type of status
5692 * NO_ERROR -- success
5693 * none-zero failure code
5694 *==========================================================================*/
release()5695 int QCamera2HardwareInterface::release()
5696 {
5697 // stop and delete all channels
5698 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
5699 if (m_channels[i] != NULL) {
5700 stopChannel((qcamera_ch_type_enum_t)i);
5701 delChannel((qcamera_ch_type_enum_t)i);
5702 }
5703 }
5704
5705 return NO_ERROR;
5706 }
5707
5708 /*===========================================================================
5709 * FUNCTION : dump
5710 *
5711 * DESCRIPTION: camera status dump impl
5712 *
5713 * PARAMETERS :
5714 * @fd : fd for the buffer to be dumped with camera status
5715 *
5716 * RETURN : int32_t type of status
5717 * NO_ERROR -- success
5718 * none-zero failure code
5719 *==========================================================================*/
dump(int fd)5720 int QCamera2HardwareInterface::dump(int fd)
5721 {
5722 dprintf(fd, "\n Camera HAL information Begin \n");
5723 dprintf(fd, "Camera ID: %d \n", mCameraId);
5724 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
5725 dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
5726 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
5727 dprintf(fd, "\n Camera HAL information End \n");
5728
5729 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
5730 debug level property */
5731 mParameters.updateDebugLevel();
5732 return NO_ERROR;
5733 }
5734
5735 /*===========================================================================
5736 * FUNCTION : processAPI
5737 *
5738 * DESCRIPTION: process API calls from upper layer
5739 *
5740 * PARAMETERS :
5741 * @api : API to be processed
5742 * @api_payload : ptr to API payload if any
5743 *
5744 * RETURN : int32_t type of status
5745 * NO_ERROR -- success
5746 * none-zero failure code
5747 *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)5748 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
5749 {
5750 int ret = DEAD_OBJECT;
5751
5752 if (m_smThreadActive) {
5753 ret = m_stateMachine.procAPI(api, api_payload);
5754 }
5755
5756 return ret;
5757 }
5758
5759 /*===========================================================================
5760 * FUNCTION : processEvt
5761 *
5762 * DESCRIPTION: process Evt from backend via mm-camera-interface
5763 *
5764 * PARAMETERS :
5765 * @evt : event type to be processed
5766 * @evt_payload : ptr to event payload if any
5767 *
5768 * RETURN : int32_t type of status
5769 * NO_ERROR -- success
5770 * none-zero failure code
5771 *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)5772 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
5773 {
5774 return m_stateMachine.procEvt(evt, evt_payload);
5775 }
5776
5777 /*===========================================================================
5778 * FUNCTION : processSyncEvt
5779 *
5780 * DESCRIPTION: process synchronous Evt from backend
5781 *
5782 * PARAMETERS :
5783 * @evt : event type to be processed
5784 * @evt_payload : ptr to event payload if any
5785 *
5786 * RETURN : int32_t type of status
5787 * NO_ERROR -- success
5788 * none-zero failure code
5789 *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)5790 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
5791 {
5792 int rc = NO_ERROR;
5793
5794 pthread_mutex_lock(&m_evtLock);
5795 rc = processEvt(evt, evt_payload);
5796 if (rc == NO_ERROR) {
5797 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
5798 while (m_evtResult.request_api != evt) {
5799 pthread_cond_wait(&m_evtCond, &m_evtLock);
5800 }
5801 rc = m_evtResult.status;
5802 }
5803 pthread_mutex_unlock(&m_evtLock);
5804
5805 return rc;
5806 }
5807
5808 /*===========================================================================
5809 * FUNCTION : evtHandle
5810 *
5811 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
5812 *
5813 * PARAMETERS :
5814 * @camera_handle : event type to be processed
5815 * @evt : ptr to event
5816 * @user_data : user data ptr
5817 *
5818 * RETURN : none
5819 *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)5820 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
5821 mm_camera_event_t *evt,
5822 void *user_data)
5823 {
5824 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
5825 if (obj && evt) {
5826 mm_camera_event_t *payload =
5827 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
5828 if (NULL != payload) {
5829 *payload = *evt;
5830 //peek into the event, if this is an eztune event from server,
5831 //then we don't need to post it to the SM Qs, we shud directly
5832 //spawn a thread and get the job done (jpeg or raw snapshot)
5833 switch (payload->server_event_type) {
5834 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
5835 //Received JPEG trigger from eztune
5836 if (false == obj->m_bIntJpegEvtPending) {
5837 pthread_mutex_lock(&obj->m_int_lock);
5838 obj->m_bIntJpegEvtPending = true;
5839 pthread_mutex_unlock(&obj->m_int_lock);
5840 obj->takePictureInternal();
5841 }
5842 free(payload);
5843 break;
5844 case CAM_EVENT_TYPE_INT_TAKE_RAW:
5845 //Received RAW trigger from eztune
5846 if (false == obj->m_bIntRawEvtPending) {
5847 pthread_mutex_lock(&obj->m_int_lock);
5848 obj->m_bIntRawEvtPending = true;
5849 pthread_mutex_unlock(&obj->m_int_lock);
5850 obj->takePictureInternal();
5851 }
5852 free(payload);
5853 break;
5854 case CAM_EVENT_TYPE_DAEMON_DIED:
5855 {
5856 Mutex::Autolock l(obj->mDefLock);
5857 obj->mDefCond.broadcast();
5858 LOGH("broadcast mDefCond signal\n");
5859 }
5860 default:
5861 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
5862 break;
5863 }
5864 }
5865 } else {
5866 LOGE("NULL user_data");
5867 }
5868 }
5869
5870 /*===========================================================================
5871 * FUNCTION : jpegEvtHandle
5872 *
5873 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
5874 *
5875 * PARAMETERS :
5876 * @status : status of jpeg job
5877 * @client_hdl: jpeg client handle
5878 * @jobId : jpeg job Id
5879 * @p_ouput : ptr to jpeg output result struct
5880 * @userdata : user data ptr
5881 *
5882 * RETURN : none
5883 *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)5884 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
5885 uint32_t /*client_hdl*/,
5886 uint32_t jobId,
5887 mm_jpeg_output_t *p_output,
5888 void *userdata)
5889 {
5890 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
5891 if (obj) {
5892 qcamera_jpeg_evt_payload_t *payload =
5893 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
5894 if (NULL != payload) {
5895 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
5896 payload->status = status;
5897 payload->jobId = jobId;
5898 if (p_output != NULL) {
5899 payload->out_data = *p_output;
5900 }
5901 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
5902 }
5903 } else {
5904 LOGE("NULL user_data");
5905 }
5906 }
5907
5908 /*===========================================================================
5909 * FUNCTION : thermalEvtHandle
5910 *
5911 * DESCRIPTION: routine to handle thermal event notification
5912 *
5913 * PARAMETERS :
5914 * @level : thermal level
5915 * @userdata : userdata passed in during registration
5916 * @data : opaque data from thermal client
5917 *
5918 * RETURN : int32_t type of status
5919 * NO_ERROR -- success
5920 * none-zero failure code
5921 *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t * level,void * userdata,void * data)5922 int QCamera2HardwareInterface::thermalEvtHandle(
5923 qcamera_thermal_level_enum_t *level, void *userdata, void *data)
5924 {
5925 if (!mCameraOpened) {
5926 LOGH("Camera is not opened, no need to handle thermal evt");
5927 return NO_ERROR;
5928 }
5929
5930 // Make sure thermal events are logged
5931 LOGH("level = %d, userdata = %p, data = %p",
5932 *level, userdata, data);
5933 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
5934 // becomes an aync call. This also means we can only pass payload
5935 // by value, not by address.
5936 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
5937 }
5938
5939 /*===========================================================================
5940 * FUNCTION : sendEvtNotify
5941 *
5942 * DESCRIPTION: send event notify to notify thread
5943 *
5944 * PARAMETERS :
5945 * @msg_type: msg type to be sent
5946 * @ext1 : optional extension1
5947 * @ext2 : optional extension2
5948 *
5949 * RETURN : int32_t type of status
5950 * NO_ERROR -- success
5951 * none-zero failure code
5952 *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)5953 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
5954 int32_t ext1,
5955 int32_t ext2)
5956 {
5957 qcamera_callback_argm_t cbArg;
5958 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
5959 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
5960 cbArg.msg_type = msg_type;
5961 cbArg.ext1 = ext1;
5962 cbArg.ext2 = ext2;
5963 return m_cbNotifier.notifyCallback(cbArg);
5964 }
5965
5966 /*===========================================================================
5967 * FUNCTION : processAEInfo
5968 *
5969 * DESCRIPTION: process AE updates
5970 *
5971 * PARAMETERS :
5972 * @ae_params: current AE parameters
5973 *
5974 * RETURN : None
5975 *==========================================================================*/
processAEInfo(cam_3a_params_t & ae_params)5976 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
5977 {
5978 mParameters.updateAEInfo(ae_params);
5979 if (mParameters.isInstantAECEnabled()) {
5980 // Reset Instant AEC info only if instant aec enabled.
5981 bool bResetInstantAec = false;
5982 if (ae_params.settled) {
5983 // If AEC settled, reset instant AEC
5984 bResetInstantAec = true;
5985 } else if ((mParameters.isInstantCaptureEnabled()) &&
5986 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
5987 // if AEC not settled, and instant capture enabled,
5988 // reset instant AEC only when frame count is
5989 // more or equal to AEC frame bound value.
5990 bResetInstantAec = true;
5991 } else if ((mParameters.isInstantAECEnabled()) &&
5992 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
5993 // if AEC not settled, and only instant AEC enabled,
5994 // reset instant AEC only when frame count is
5995 // more or equal to AEC skip display frame bound value.
5996 bResetInstantAec = true;
5997 }
5998
5999 if (bResetInstantAec) {
6000 LOGD("setting instant AEC to false");
6001 mParameters.setInstantAEC(false, true);
6002 mInstantAecFrameCount = 0;
6003 }
6004 }
6005 return NO_ERROR;
6006 }
6007
6008 /*===========================================================================
6009 * FUNCTION : processFocusPositionInfo
6010 *
6011 * DESCRIPTION: process AF updates
6012 *
6013 * PARAMETERS :
6014 * @cur_pos_info: current lens position
6015 *
6016 * RETURN : None
6017 *==========================================================================*/
processFocusPositionInfo(cam_focus_pos_info_t & cur_pos_info)6018 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
6019 {
6020 mParameters.updateCurrentFocusPosition(cur_pos_info);
6021 return NO_ERROR;
6022 }
6023
6024 /*===========================================================================
6025 * FUNCTION : processAutoFocusEvent
6026 *
6027 * DESCRIPTION: process auto focus event
6028 *
6029 * PARAMETERS :
6030 * @focus_data: struct containing auto focus result info
6031 *
6032 * RETURN : int32_t type of status
6033 * NO_ERROR -- success
6034 * none-zero failure code
6035 *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)6036 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
6037 {
6038 int32_t ret = NO_ERROR;
6039 LOGH("E");
6040
6041 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
6042 // Ignore focus updates
6043 LOGH("X Secondary Camera, no need to process!! ");
6044 return ret;
6045 }
6046 cam_focus_mode_type focusMode = mParameters.getFocusMode();
6047 LOGH("[AF_DBG] focusMode=%d, focusState=%d",
6048 focusMode, focus_data.focus_state);
6049
6050 switch (focusMode) {
6051 case CAM_FOCUS_MODE_AUTO:
6052 case CAM_FOCUS_MODE_MACRO:
6053 // ignore AF event if AF was already cancelled meanwhile
6054 if (!mActiveAF) {
6055 break;
6056 }
6057 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6058 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6059 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6060 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
6061 mActiveAF = false; // reset the mActiveAF in this special case
6062 break;
6063 }
6064
6065 //while transitioning from CAF->Auto/Macro, we might receive CAF related
6066 //events (PASSIVE_*) due to timing. Ignore such events if any.
6067 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
6068 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6069 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
6070 break;
6071 }
6072
6073 //This is just an intermediate update to HAL indicating focus is in progress. No need
6074 //to send this event to app. Same applies to INACTIVE state as well.
6075 if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
6076 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6077 break;
6078 }
6079 // update focus distance
6080 mParameters.updateFocusDistances(&focus_data.focus_dist);
6081
6082 //flush any old snapshot frames in ZSL Q which are not focused.
6083 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6084 QCameraPicChannel *pZSLChannel =
6085 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6086 if (NULL != pZSLChannel) {
6087 //flush the zsl-buffer
6088 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6089 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6090 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6091 }
6092 }
6093
6094 //send event to app finally
6095 LOGI("Send AF DOne event to app");
6096 ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6097 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
6098 break;
6099 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
6100 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
6101
6102 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6103 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6104 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6105 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
6106 mActiveAF = false; // reset the mActiveAF in this special case
6107 break;
6108 }
6109
6110 //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
6111 //process/wait for only ACTIVE_* events.
6112 if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6113 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6114 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
6115 break;
6116 }
6117
6118 //These are the AF states for which we need to send notification to app in CAF mode.
6119 //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
6120 //AF is triggered while in CAF mode)
6121 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6122 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6123 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6124 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6125
6126 // update focus distance
6127 mParameters.updateFocusDistances(&focus_data.focus_dist);
6128
6129 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6130 QCameraPicChannel *pZSLChannel =
6131 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6132 if (NULL != pZSLChannel) {
6133 //flush the zsl-buffer
6134 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6135 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6136 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6137 }
6138 }
6139
6140 if (mActiveAF) {
6141 LOGI("Send AF Done event to app");
6142 }
6143 ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6144 ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6145 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
6146 }
6147 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
6148 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
6149 break;
6150 case CAM_FOCUS_MODE_INFINITY:
6151 case CAM_FOCUS_MODE_FIXED:
6152 case CAM_FOCUS_MODE_EDOF:
6153 default:
6154 LOGH("no ops for autofocus event in focusmode %d", focusMode);
6155 break;
6156 }
6157
6158 //Reset mActiveAF once we receive focus done event
6159 if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6160 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6161 mActiveAF = false;
6162 }
6163
6164 LOGH("X");
6165 return ret;
6166 }
6167
6168 /*===========================================================================
6169 * FUNCTION : processZoomEvent
6170 *
6171 * DESCRIPTION: process zoom event
6172 *
6173 * PARAMETERS :
6174 * @crop_info : crop info as a result of zoom operation
6175 *
6176 * RETURN : int32_t type of status
6177 * NO_ERROR -- success
6178 * none-zero failure code
6179 *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)6180 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
6181 {
6182 int32_t ret = NO_ERROR;
6183
6184 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6185 if (m_channels[i] != NULL) {
6186 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
6187 }
6188 }
6189 return ret;
6190 }
6191
6192 /*===========================================================================
6193 * FUNCTION : processZSLCaptureDone
6194 *
6195 * DESCRIPTION: process ZSL capture done events
6196 *
6197 * PARAMETERS : None
6198 *
6199 * RETURN : int32_t type of status
6200 * NO_ERROR -- success
6201 * none-zero failure code
6202 *==========================================================================*/
processZSLCaptureDone()6203 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
6204 {
6205 int rc = NO_ERROR;
6206
6207 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
6208 rc = unconfigureAdvancedCapture();
6209 }
6210
6211 return rc;
6212 }
6213
6214 /*===========================================================================
6215 * FUNCTION : processRetroAECUnlock
6216 *
6217 * DESCRIPTION: process retro burst AEC unlock events
6218 *
6219 * PARAMETERS : None
6220 *
6221 * RETURN : int32_t type of status
6222 * NO_ERROR -- success
6223 * none-zero failure code
6224 *==========================================================================*/
processRetroAECUnlock()6225 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
6226 {
6227 int rc = NO_ERROR;
6228
6229 LOGH("LED assisted AF Release AEC Lock");
6230 rc = mParameters.setAecLock("false");
6231 if (NO_ERROR != rc) {
6232 LOGE("Error setting AEC lock");
6233 return rc;
6234 }
6235
6236 rc = mParameters.commitParameters();
6237 if (NO_ERROR != rc) {
6238 LOGE("Error during camera parameter commit");
6239 } else {
6240 m_bLedAfAecLock = FALSE;
6241 }
6242
6243 return rc;
6244 }
6245
6246 /*===========================================================================
6247 * FUNCTION : processHDRData
6248 *
6249 * DESCRIPTION: process HDR scene events
6250 *
6251 * PARAMETERS :
6252 * @hdr_scene : HDR scene event data
6253 *
6254 * RETURN : int32_t type of status
6255 * NO_ERROR -- success
6256 * none-zero failure code
6257 *==========================================================================*/
processHDRData(__unused cam_asd_hdr_scene_data_t hdr_scene)6258 int32_t QCamera2HardwareInterface::processHDRData(
6259 __unused cam_asd_hdr_scene_data_t hdr_scene)
6260 {
6261 int rc = NO_ERROR;
6262
6263 #ifndef VANILLA_HAL
6264 if (hdr_scene.is_hdr_scene &&
6265 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
6266 mParameters.isAutoHDREnabled()) {
6267 m_HDRSceneEnabled = true;
6268 } else {
6269 m_HDRSceneEnabled = false;
6270 }
6271 mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
6272
6273 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6274
6275 size_t data_len = sizeof(int);
6276 size_t buffer_len = 1 *sizeof(int) //meta type
6277 + 1 *sizeof(int) //data len
6278 + 1 *sizeof(int); //data
6279 camera_memory_t *hdrBuffer = mGetMemory(-1,
6280 buffer_len,
6281 1,
6282 mCallbackCookie);
6283 if ( NULL == hdrBuffer ) {
6284 LOGE("Not enough memory for auto HDR data");
6285 return NO_MEMORY;
6286 }
6287
6288 int *pHDRData = (int *)hdrBuffer->data;
6289 if (pHDRData == NULL) {
6290 LOGE("memory data ptr is NULL");
6291 return UNKNOWN_ERROR;
6292 }
6293
6294 pHDRData[0] = CAMERA_META_DATA_HDR;
6295 pHDRData[1] = (int)data_len;
6296 pHDRData[2] = m_HDRSceneEnabled;
6297
6298 qcamera_callback_argm_t cbArg;
6299 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6300 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6301 cbArg.msg_type = CAMERA_MSG_META_DATA;
6302 cbArg.data = hdrBuffer;
6303 cbArg.user_data = hdrBuffer;
6304 cbArg.cookie = this;
6305 cbArg.release_cb = releaseCameraMemory;
6306 rc = m_cbNotifier.notifyCallback(cbArg);
6307 if (rc != NO_ERROR) {
6308 LOGE("fail sending auto HDR notification");
6309 hdrBuffer->release(hdrBuffer);
6310 }
6311 }
6312
6313 LOGH("hdr_scene_data: processHDRData: %d %f",
6314 hdr_scene.is_hdr_scene,
6315 hdr_scene.hdr_confidence);
6316
6317 #endif
6318 return rc;
6319 }
6320
6321 /*===========================================================================
6322 * FUNCTION : transAwbMetaToParams
6323 *
6324 * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
6325 *
6326 * PARAMETERS :
6327 * @awb_params : awb params from metadata callback
6328 *
6329 * RETURN : int32_t type of status
6330 * NO_ERROR -- success
6331 * none-zero failure code
6332 *==========================================================================*/
transAwbMetaToParams(cam_awb_params_t & awb_params)6333 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
6334 {
6335 mParameters.updateAWBParams(awb_params);
6336 return NO_ERROR;
6337 }
6338
6339 /*===========================================================================
6340 * FUNCTION : processPrepSnapshotDone
6341 *
6342 * DESCRIPTION: process prep snapshot done event
6343 *
6344 * PARAMETERS :
6345 * @prep_snapshot_state : state of prepare snapshot done. In other words,
6346 * i.e. whether need future frames for capture.
6347 *
6348 * RETURN : int32_t type of status
6349 * NO_ERROR -- success
6350 * none-zero failure code
6351 *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)6352 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
6353 cam_prep_snapshot_state_t prep_snapshot_state)
6354 {
6355 int32_t ret = NO_ERROR;
6356 LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
6357 prep_snapshot_state);
6358 if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
6359 prep_snapshot_state == NEED_FUTURE_FRAME) {
6360 LOGH("already handled in mm-camera-intf, no ops here");
6361 if (isRetroPicture()) {
6362 mParameters.setAecLock("true");
6363 mParameters.commitParameters();
6364 m_bLedAfAecLock = TRUE;
6365 }
6366 }
6367 return ret;
6368 }
6369
6370 /*===========================================================================
6371 * FUNCTION : processASDUpdate
6372 *
6373 * DESCRIPTION: process ASD update event
6374 *
6375 * PARAMETERS :
6376 * @scene: selected scene mode
6377 *
6378 * RETURN : int32_t type of status
6379 * NO_ERROR -- success
6380 * none-zero failure code
6381 *==========================================================================*/
processASDUpdate(__unused cam_asd_decision_t asd_decision)6382 int32_t QCamera2HardwareInterface::processASDUpdate(
6383 __unused cam_asd_decision_t asd_decision)
6384 {
6385 size_t data_len = sizeof(cam_auto_scene_t);
6386 size_t buffer_len = 1 *sizeof(int) //meta type
6387 + 1 *sizeof(int) //data len
6388 + data_len; //data
6389 camera_memory_t *asdBuffer = mGetMemory(-1,
6390 buffer_len,
6391 1,
6392 mCallbackCookie);
6393 if ( NULL == asdBuffer ) {
6394 LOGE("Not enough memory for histogram data");
6395 return NO_MEMORY;
6396 }
6397
6398 int *pASDData = (int *)asdBuffer->data;
6399 if (pASDData == NULL) {
6400 LOGE("memory data ptr is NULL");
6401 return UNKNOWN_ERROR;
6402 }
6403
6404 #ifndef VANILLA_HAL
6405 pASDData[0] = CAMERA_META_DATA_ASD;
6406 pASDData[1] = (int)data_len;
6407 pASDData[2] = asd_decision.detected_scene;
6408
6409 qcamera_callback_argm_t cbArg;
6410 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6411 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6412 cbArg.msg_type = CAMERA_MSG_META_DATA;
6413 cbArg.data = asdBuffer;
6414 cbArg.user_data = asdBuffer;
6415 cbArg.cookie = this;
6416 cbArg.release_cb = releaseCameraMemory;
6417 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
6418 if (rc != NO_ERROR) {
6419 LOGE("fail sending notification");
6420 asdBuffer->release(asdBuffer);
6421 }
6422 #endif
6423 return NO_ERROR;
6424
6425 }
6426
6427 /*===========================================================================
6428 * FUNCTION : processJpegNotify
6429 *
6430 * DESCRIPTION: process jpeg event
6431 *
6432 * PARAMETERS :
6433 * @jpeg_evt: ptr to jpeg event payload
6434 *
6435 * RETURN : int32_t type of status
6436 * NO_ERROR -- success
6437 * none-zero failure code
6438 *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)6439 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
6440 {
6441 return m_postprocessor.processJpegEvt(jpeg_evt);
6442 }
6443
6444 /*===========================================================================
6445 * FUNCTION : lockAPI
6446 *
6447 * DESCRIPTION: lock to process API
6448 *
6449 * PARAMETERS : none
6450 *
6451 * RETURN : none
6452 *==========================================================================*/
lockAPI()6453 void QCamera2HardwareInterface::lockAPI()
6454 {
6455 pthread_mutex_lock(&m_lock);
6456 }
6457
6458 /*===========================================================================
6459 * FUNCTION : waitAPIResult
6460 *
6461 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
6462 * return only cerntain API event type arrives
6463 *
6464 * PARAMETERS :
6465 * @api_evt : API event type
6466 *
6467 * RETURN : none
6468 *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)6469 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
6470 qcamera_api_result_t *apiResult)
6471 {
6472 LOGD("wait for API result of evt (%d)", api_evt);
6473 int resultReceived = 0;
6474 while (!resultReceived) {
6475 pthread_cond_wait(&m_cond, &m_lock);
6476 if (m_apiResultList != NULL) {
6477 api_result_list *apiResultList = m_apiResultList;
6478 api_result_list *apiResultListPrevious = m_apiResultList;
6479 while (apiResultList != NULL) {
6480 if (apiResultList->result.request_api == api_evt) {
6481 resultReceived = 1;
6482 *apiResult = apiResultList->result;
6483 apiResultListPrevious->next = apiResultList->next;
6484 if (apiResultList == m_apiResultList) {
6485 m_apiResultList = apiResultList->next;
6486 }
6487 free(apiResultList);
6488 break;
6489 }
6490 else {
6491 apiResultListPrevious = apiResultList;
6492 apiResultList = apiResultList->next;
6493 }
6494 }
6495 }
6496 }
6497 LOGD("return (%d) from API result wait for evt (%d)",
6498 apiResult->status, api_evt);
6499 }
6500
6501
6502 /*===========================================================================
6503 * FUNCTION : unlockAPI
6504 *
6505 * DESCRIPTION: API processing is done, unlock
6506 *
6507 * PARAMETERS : none
6508 *
6509 * RETURN : none
6510 *==========================================================================*/
unlockAPI()6511 void QCamera2HardwareInterface::unlockAPI()
6512 {
6513 pthread_mutex_unlock(&m_lock);
6514 }
6515
6516 /*===========================================================================
6517 * FUNCTION : signalAPIResult
6518 *
6519 * DESCRIPTION: signal condition viarable that cerntain API event type arrives
6520 *
6521 * PARAMETERS :
6522 * @result : API result
6523 *
6524 * RETURN : none
6525 *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)6526 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
6527 {
6528
6529 pthread_mutex_lock(&m_lock);
6530 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
6531 if (apiResult == NULL) {
6532 LOGE("ERROR: malloc for api result failed, Result will not be sent");
6533 goto malloc_failed;
6534 }
6535 apiResult->result = *result;
6536 apiResult->next = NULL;
6537 if (m_apiResultList == NULL) m_apiResultList = apiResult;
6538 else {
6539 api_result_list *apiResultList = m_apiResultList;
6540 while(apiResultList->next != NULL) apiResultList = apiResultList->next;
6541 apiResultList->next = apiResult;
6542 }
6543 malloc_failed:
6544 pthread_cond_broadcast(&m_cond);
6545 pthread_mutex_unlock(&m_lock);
6546 }
6547
6548 /*===========================================================================
6549 * FUNCTION : signalEvtResult
6550 *
6551 * DESCRIPTION: signal condition variable that certain event was processed
6552 *
6553 * PARAMETERS :
6554 * @result : Event result
6555 *
6556 * RETURN : none
6557 *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)6558 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
6559 {
6560 pthread_mutex_lock(&m_evtLock);
6561 m_evtResult = *result;
6562 pthread_cond_signal(&m_evtCond);
6563 pthread_mutex_unlock(&m_evtLock);
6564 }
6565
prepareRawStream(QCameraChannel * curChannel)6566 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
6567 {
6568 int32_t rc = NO_ERROR;
6569 cam_dimension_t str_dim,max_dim;
6570 QCameraChannel *pChannel;
6571
6572 max_dim.width = 0;
6573 max_dim.height = 0;
6574
6575 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
6576 if (m_channels[j] != NULL) {
6577 pChannel = m_channels[j];
6578 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
6579 QCameraStream *pStream = pChannel->getStreamByIndex(i);
6580 if (pStream != NULL) {
6581 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
6582 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
6583 continue;
6584 }
6585 pStream->getFrameDimension(str_dim);
6586 if (str_dim.width > max_dim.width) {
6587 max_dim.width = str_dim.width;
6588 }
6589 if (str_dim.height > max_dim.height) {
6590 max_dim.height = str_dim.height;
6591 }
6592 }
6593 }
6594 }
6595 }
6596
6597 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
6598 QCameraStream *pStream = curChannel->getStreamByIndex(i);
6599 if (pStream != NULL) {
6600 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
6601 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
6602 continue;
6603 }
6604 pStream->getFrameDimension(str_dim);
6605 if (str_dim.width > max_dim.width) {
6606 max_dim.width = str_dim.width;
6607 }
6608 if (str_dim.height > max_dim.height) {
6609 max_dim.height = str_dim.height;
6610 }
6611 }
6612 }
6613 rc = mParameters.updateRAW(max_dim);
6614 return rc;
6615 }
6616 /*===========================================================================
6617 * FUNCTION : addStreamToChannel
6618 *
6619 * DESCRIPTION: add a stream into a channel
6620 *
6621 * PARAMETERS :
6622 * @pChannel : ptr to channel obj
6623 * @streamType : type of stream to be added
6624 * @streamCB : callback of stream
6625 * @userData : user data ptr to callback
6626 *
6627 * RETURN : int32_t type of status
6628 * NO_ERROR -- success
6629 * none-zero failure code
6630 *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)6631 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
6632 cam_stream_type_t streamType,
6633 stream_cb_routine streamCB,
6634 void *userData)
6635 {
6636 int32_t rc = NO_ERROR;
6637
6638 if (streamType == CAM_STREAM_TYPE_RAW) {
6639 prepareRawStream(pChannel);
6640 }
6641 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
6642 if (pStreamInfo == NULL) {
6643 LOGE("no mem for stream info buf");
6644 return NO_MEMORY;
6645 }
6646 uint8_t minStreamBufNum = getBufNumRequired(streamType);
6647 bool bDynAllocBuf = false;
6648 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
6649 bDynAllocBuf = true;
6650 }
6651
6652 cam_padding_info_t padding_info;
6653 if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
6654 padding_info =
6655 gCamCapability[mCameraId]->analysis_padding_info;
6656 } else {
6657 padding_info =
6658 gCamCapability[mCameraId]->padding_info;
6659 if (streamType == CAM_STREAM_TYPE_PREVIEW) {
6660 padding_info.width_padding = mSurfaceStridePadding;
6661 padding_info.height_padding = CAM_PAD_TO_2;
6662 }
6663 if((!needReprocess())
6664 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
6665 || (!mParameters.isLLNoiseEnabled())) {
6666 padding_info.offset_info.offset_x = 0;
6667 padding_info.offset_info.offset_y = 0;
6668 }
6669 }
6670
6671 bool deferAllocation = needDeferred(streamType);
6672 LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
6673 deferAllocation, bDynAllocBuf, streamType);
6674 rc = pChannel->addStream(*this,
6675 pStreamInfo,
6676 NULL,
6677 minStreamBufNum,
6678 &padding_info,
6679 streamCB, userData,
6680 bDynAllocBuf,
6681 deferAllocation);
6682
6683 if (rc != NO_ERROR) {
6684 LOGE("add stream type (%d) failed, ret = %d",
6685 streamType, rc);
6686 return rc;
6687 }
6688
6689 return rc;
6690 }
6691
6692 /*===========================================================================
6693 * FUNCTION : addPreviewChannel
6694 *
6695 * DESCRIPTION: add a preview channel that contains a preview stream
6696 *
6697 * PARAMETERS : none
6698 *
6699 * RETURN : int32_t type of status
6700 * NO_ERROR -- success
6701 * none-zero failure code
6702 *==========================================================================*/
addPreviewChannel()6703 int32_t QCamera2HardwareInterface::addPreviewChannel()
6704 {
6705 int32_t rc = NO_ERROR;
6706 QCameraChannel *pChannel = NULL;
6707 char value[PROPERTY_VALUE_MAX];
6708 bool raw_yuv = false;
6709
6710
6711 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
6712 // if we had preview channel before, delete it first
6713 delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
6714 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
6715 }
6716
6717 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
6718 mCameraHandle->ops);
6719 if (NULL == pChannel) {
6720 LOGE("no mem for preview channel");
6721 return NO_MEMORY;
6722 }
6723
6724 // preview only channel, don't need bundle attr and cb
6725 rc = pChannel->init(NULL, NULL, NULL);
6726 if (rc != NO_ERROR) {
6727 LOGE("init preview channel failed, ret = %d", rc);
6728 return rc;
6729 }
6730
6731 // meta data stream always coexists with preview if applicable
6732 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
6733 metadata_stream_cb_routine, this);
6734 if (rc != NO_ERROR) {
6735 LOGE("add metadata stream failed, ret = %d", rc);
6736 return rc;
6737 }
6738
6739 if (isRdiMode()) {
6740 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
6741 rdi_mode_stream_cb_routine, this);
6742 } else {
6743 if (isNoDisplayMode()) {
6744 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
6745 nodisplay_preview_stream_cb_routine, this);
6746 } else {
6747 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
6748 preview_stream_cb_routine, this);
6749 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
6750 synchronous_stream_cb_routine);
6751 }
6752 }
6753
6754 if (((mParameters.fdModeInVideo())
6755 || (mParameters.getDcrf() == true)
6756 || (mParameters.getRecordingHintValue() != true))
6757 && (!mParameters.isSecureMode())) {
6758 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
6759 NULL, this);
6760 if (rc != NO_ERROR) {
6761 LOGE("add Analysis stream failed, ret = %d", rc);
6762 return rc;
6763 }
6764 }
6765
6766 property_get("persist.camera.raw_yuv", value, "0");
6767 raw_yuv = atoi(value) > 0 ? true : false;
6768 if ( raw_yuv ) {
6769 rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
6770 preview_raw_stream_cb_routine,this);
6771 if ( rc != NO_ERROR ) {
6772 LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
6773 delete pChannel;
6774 return rc;
6775 }
6776 }
6777
6778 if (rc != NO_ERROR) {
6779 LOGE("add preview stream failed, ret = %d", rc);
6780 delete pChannel;
6781 return rc;
6782 }
6783
6784 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
6785 return rc;
6786 }
6787
6788 /*===========================================================================
6789 * FUNCTION : addVideoChannel
6790 *
6791 * DESCRIPTION: add a video channel that contains a video stream
6792 *
6793 * PARAMETERS : none
6794 *
6795 * RETURN : int32_t type of status
6796 * NO_ERROR -- success
6797 * none-zero failure code
6798 *==========================================================================*/
addVideoChannel()6799 int32_t QCamera2HardwareInterface::addVideoChannel()
6800 {
6801 int32_t rc = NO_ERROR;
6802 QCameraVideoChannel *pChannel = NULL;
6803
6804 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
6805 // if we had video channel before, delete it first
6806 delete m_channels[QCAMERA_CH_TYPE_VIDEO];
6807 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
6808 }
6809
6810 pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
6811 mCameraHandle->ops);
6812 if (NULL == pChannel) {
6813 LOGE("no mem for video channel");
6814 return NO_MEMORY;
6815 }
6816
6817 if (isLowPowerMode()) {
6818 mm_camera_channel_attr_t attr;
6819 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
6820 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
6821 attr.look_back = 0; //wait for future frame for liveshot
6822 attr.post_frame_skip = mParameters.getZSLBurstInterval();
6823 attr.water_mark = 1; //hold min buffers possible in Q
6824 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
6825 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
6826 } else {
6827 // preview only channel, don't need bundle attr and cb
6828 rc = pChannel->init(NULL, NULL, NULL);
6829 }
6830
6831 if (rc != 0) {
6832 LOGE("init video channel failed, ret = %d", rc);
6833 delete pChannel;
6834 return rc;
6835 }
6836
6837 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
6838 video_stream_cb_routine, this);
6839 if (rc != NO_ERROR) {
6840 LOGE("add video stream failed, ret = %d", rc);
6841 delete pChannel;
6842 return rc;
6843 }
6844
6845 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
6846 return rc;
6847 }
6848
6849 /*===========================================================================
6850 * FUNCTION : addSnapshotChannel
6851 *
6852 * DESCRIPTION: add a snapshot channel that contains a snapshot stream
6853 *
6854 * PARAMETERS : none
6855 *
6856 * RETURN : int32_t type of status
6857 * NO_ERROR -- success
6858 * none-zero failure code
6859 * NOTE : Add this channel for live snapshot usecase. Regular capture will
6860 * use addCaptureChannel.
6861 *==========================================================================*/
addSnapshotChannel()6862 int32_t QCamera2HardwareInterface::addSnapshotChannel()
6863 {
6864 int32_t rc = NO_ERROR;
6865 QCameraChannel *pChannel = NULL;
6866
6867 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
6868 // if we had ZSL channel before, delete it first
6869 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
6870 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
6871 }
6872
6873 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
6874 mCameraHandle->ops);
6875 if (NULL == pChannel) {
6876 LOGE("no mem for snapshot channel");
6877 return NO_MEMORY;
6878 }
6879
6880 mm_camera_channel_attr_t attr;
6881 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
6882 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
6883 attr.look_back = 0; //wait for future frame for liveshot
6884 attr.post_frame_skip = mParameters.getZSLBurstInterval();
6885 attr.water_mark = 1; //hold min buffers possible in Q
6886 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
6887 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
6888 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
6889 if (rc != NO_ERROR) {
6890 LOGE("init snapshot channel failed, ret = %d", rc);
6891 delete pChannel;
6892 return rc;
6893 }
6894
6895 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
6896 NULL, NULL);
6897 if (rc != NO_ERROR) {
6898 LOGE("add snapshot stream failed, ret = %d", rc);
6899 delete pChannel;
6900 return rc;
6901 }
6902
6903 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
6904 return rc;
6905 }
6906
6907 /*===========================================================================
6908 * FUNCTION : addRawChannel
6909 *
6910 * DESCRIPTION: add a raw channel that contains a raw image stream
6911 *
6912 * PARAMETERS : none
6913 *
6914 * RETURN : int32_t type of status
6915 * NO_ERROR -- success
6916 * none-zero failure code
6917 *==========================================================================*/
addRawChannel()6918 int32_t QCamera2HardwareInterface::addRawChannel()
6919 {
6920 int32_t rc = NO_ERROR;
6921 QCameraChannel *pChannel = NULL;
6922
6923 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
6924 // if we had raw channel before, delete it first
6925 delete m_channels[QCAMERA_CH_TYPE_RAW];
6926 m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
6927 }
6928
6929 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
6930 mCameraHandle->ops);
6931 if (NULL == pChannel) {
6932 LOGE("no mem for raw channel");
6933 return NO_MEMORY;
6934 }
6935
6936 if (mParameters.getofflineRAW()) {
6937 mm_camera_channel_attr_t attr;
6938 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
6939 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
6940 attr.look_back = mParameters.getZSLBackLookCount();
6941 attr.post_frame_skip = mParameters.getZSLBurstInterval();
6942 attr.water_mark = 1;
6943 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
6944 rc = pChannel->init(&attr, raw_channel_cb_routine, this);
6945 if (rc != NO_ERROR) {
6946 LOGE("init RAW channel failed, ret = %d", rc);
6947 delete pChannel;
6948 return rc;
6949 }
6950 } else {
6951 rc = pChannel->init(NULL, NULL, NULL);
6952 if (rc != NO_ERROR) {
6953 LOGE("init raw channel failed, ret = %d", rc);
6954 delete pChannel;
6955 return rc;
6956 }
6957 }
6958
6959 if (!mParameters.isZSLMode()) {
6960 // meta data stream always coexists with snapshot in regular RAW capture case
6961 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
6962 metadata_stream_cb_routine, this);
6963 if (rc != NO_ERROR) {
6964 LOGE("add metadata stream failed, ret = %d", rc);
6965 delete pChannel;
6966 return rc;
6967 }
6968 }
6969
6970 if (mParameters.getofflineRAW()) {
6971 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
6972 NULL, this);
6973 } else {
6974 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
6975 raw_stream_cb_routine, this);
6976 }
6977 if (rc != NO_ERROR) {
6978 LOGE("add snapshot stream failed, ret = %d", rc);
6979 delete pChannel;
6980 return rc;
6981 }
6982 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
6983 return rc;
6984 }
6985
6986 /*===========================================================================
6987 * FUNCTION : addZSLChannel
6988 *
6989 * DESCRIPTION: add a ZSL channel that contains a preview stream and
6990 * a snapshot stream
6991 *
6992 * PARAMETERS : none
6993 *
6994 * RETURN : int32_t type of status
6995 * NO_ERROR -- success
6996 * none-zero failure code
6997 *==========================================================================*/
addZSLChannel()6998 int32_t QCamera2HardwareInterface::addZSLChannel()
6999 {
7000 int32_t rc = NO_ERROR;
7001 QCameraPicChannel *pChannel = NULL;
7002 char value[PROPERTY_VALUE_MAX];
7003 bool raw_yuv = false;
7004
7005 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
7006 // if we had ZSL channel before, delete it first
7007 delete m_channels[QCAMERA_CH_TYPE_ZSL];
7008 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
7009 }
7010
7011 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
7012 mCameraHandle->ops);
7013 if (NULL == pChannel) {
7014 LOGE("no mem for ZSL channel");
7015 return NO_MEMORY;
7016 }
7017
7018 // ZSL channel, init with bundle attr and cb
7019 mm_camera_channel_attr_t attr;
7020 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7021 if (mParameters.isSceneSelectionEnabled()) {
7022 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7023 } else {
7024 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7025 }
7026 attr.look_back = mParameters.getZSLBackLookCount();
7027 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7028 if (mParameters.isOEMFeatEnabled()) {
7029 attr.post_frame_skip++;
7030 }
7031 attr.water_mark = mParameters.getZSLQueueDepth();
7032 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7033 attr.user_expected_frame_id =
7034 mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
7035
7036 //Enabled matched queue
7037 if (getRelatedCamSyncInfo()->is_frame_sync_enabled) {
7038 LOGH("Enabling frame sync for dual camera, camera Id: %d",
7039 mCameraId);
7040 attr.enable_frame_sync = 1;
7041 }
7042 rc = pChannel->init(&attr,
7043 zsl_channel_cb,
7044 this);
7045 if (rc != 0) {
7046 LOGE("init ZSL channel failed, ret = %d", rc);
7047 delete pChannel;
7048 return rc;
7049 }
7050
7051 // meta data stream always coexists with preview if applicable
7052 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7053 metadata_stream_cb_routine, this);
7054 if (rc != NO_ERROR) {
7055 LOGE("add metadata stream failed, ret = %d", rc);
7056 delete pChannel;
7057 return rc;
7058 }
7059
7060 if (isNoDisplayMode()) {
7061 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7062 nodisplay_preview_stream_cb_routine, this);
7063 } else {
7064 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7065 preview_stream_cb_routine, this);
7066 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7067 synchronous_stream_cb_routine);
7068 }
7069 if (rc != NO_ERROR) {
7070 LOGE("add preview stream failed, ret = %d", rc);
7071 delete pChannel;
7072 return rc;
7073 }
7074
7075 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7076 NULL, this);
7077 if (rc != NO_ERROR) {
7078 LOGE("add snapshot stream failed, ret = %d", rc);
7079 delete pChannel;
7080 return rc;
7081 }
7082
7083 if (!mParameters.isSecureMode()) {
7084 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7085 NULL, this);
7086 if (rc != NO_ERROR) {
7087 LOGE("add Analysis stream failed, ret = %d", rc);
7088 delete pChannel;
7089 return rc;
7090 }
7091 }
7092
7093 property_get("persist.camera.raw_yuv", value, "0");
7094 raw_yuv = atoi(value) > 0 ? true : false;
7095 if (raw_yuv) {
7096 rc = addStreamToChannel(pChannel,
7097 CAM_STREAM_TYPE_RAW,
7098 NULL,
7099 this);
7100 if (rc != NO_ERROR) {
7101 LOGE("add raw stream failed, ret = %d", rc);
7102 delete pChannel;
7103 return rc;
7104 }
7105 }
7106
7107 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
7108 return rc;
7109 }
7110
7111 /*===========================================================================
7112 * FUNCTION : addCaptureChannel
7113 *
7114 * DESCRIPTION: add a capture channel that contains a snapshot stream
7115 * and a postview stream
7116 *
7117 * PARAMETERS : none
7118 *
7119 * RETURN : int32_t type of status
7120 * NO_ERROR -- success
7121 * none-zero failure code
7122 * NOTE : Add this channel for regular capture usecase.
7123 * For Live snapshot usecase, use addSnapshotChannel.
7124 *==========================================================================*/
addCaptureChannel()7125 int32_t QCamera2HardwareInterface::addCaptureChannel()
7126 {
7127 int32_t rc = NO_ERROR;
7128 QCameraPicChannel *pChannel = NULL;
7129 char value[PROPERTY_VALUE_MAX];
7130 bool raw_yuv = false;
7131
7132 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
7133 delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
7134 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
7135 }
7136
7137 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
7138 mCameraHandle->ops);
7139 if (NULL == pChannel) {
7140 LOGE("no mem for capture channel");
7141 return NO_MEMORY;
7142 }
7143
7144 // Capture channel, only need snapshot and postview streams start together
7145 mm_camera_channel_attr_t attr;
7146 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7147 if ( mLongshotEnabled ) {
7148 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7149 attr.look_back = mParameters.getZSLBackLookCount();
7150 attr.water_mark = mParameters.getZSLQueueDepth();
7151 } else {
7152 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7153 }
7154 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7155
7156 rc = pChannel->init(&attr,
7157 capture_channel_cb_routine,
7158 this);
7159 if (rc != NO_ERROR) {
7160 LOGE("init capture channel failed, ret = %d", rc);
7161 return rc;
7162 }
7163
7164 // meta data stream always coexists with snapshot in regular capture case
7165 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7166 metadata_stream_cb_routine, this);
7167 if (rc != NO_ERROR) {
7168 LOGE("add metadata stream failed, ret = %d", rc);
7169 return rc;
7170 }
7171
7172 if (!mLongshotEnabled) {
7173 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
7174 NULL, this);
7175
7176 if (rc != NO_ERROR) {
7177 LOGE("add postview stream failed, ret = %d", rc);
7178 return rc;
7179 }
7180 } else {
7181 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7182 preview_stream_cb_routine, this);
7183
7184 if (rc != NO_ERROR) {
7185 LOGE("add preview stream failed, ret = %d", rc);
7186 return rc;
7187 }
7188 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7189 synchronous_stream_cb_routine);
7190 }
7191
7192 if (!mParameters.getofflineRAW()) {
7193 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7194 NULL, this);
7195 if (rc != NO_ERROR) {
7196 LOGE("add snapshot stream failed, ret = %d", rc);
7197 return rc;
7198 }
7199 }
7200
7201 stream_cb_routine stream_cb = NULL;
7202 property_get("persist.camera.raw_yuv", value, "0");
7203 raw_yuv = atoi(value) > 0 ? true : false;
7204
7205 if (raw_yuv) {
7206 stream_cb = snapshot_raw_stream_cb_routine;
7207 }
7208
7209 if ((raw_yuv) || (mParameters.getofflineRAW())) {
7210 rc = addStreamToChannel(pChannel,
7211 CAM_STREAM_TYPE_RAW, stream_cb, this);
7212 if (rc != NO_ERROR) {
7213 LOGE("add raw stream failed, ret = %d", rc);
7214 return rc;
7215 }
7216 }
7217
7218 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
7219 return rc;
7220 }
7221
7222 /*===========================================================================
7223 * FUNCTION : addMetaDataChannel
7224 *
7225 * DESCRIPTION: add a meta data channel that contains a metadata stream
7226 *
7227 * PARAMETERS : none
7228 *
7229 * RETURN : int32_t type of status
7230 * NO_ERROR -- success
7231 * none-zero failure code
7232 *==========================================================================*/
addMetaDataChannel()7233 int32_t QCamera2HardwareInterface::addMetaDataChannel()
7234 {
7235 int32_t rc = NO_ERROR;
7236 QCameraChannel *pChannel = NULL;
7237
7238 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
7239 delete m_channels[QCAMERA_CH_TYPE_METADATA];
7240 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
7241 }
7242
7243 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
7244 mCameraHandle->ops);
7245 if (NULL == pChannel) {
7246 LOGE("no mem for metadata channel");
7247 return NO_MEMORY;
7248 }
7249
7250 rc = pChannel->init(NULL,
7251 NULL,
7252 NULL);
7253 if (rc != NO_ERROR) {
7254 LOGE("init metadata channel failed, ret = %d", rc);
7255 delete pChannel;
7256 return rc;
7257 }
7258
7259 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7260 metadata_stream_cb_routine, this);
7261 if (rc != NO_ERROR) {
7262 LOGE("add metadata stream failed, ret = %d", rc);
7263 delete pChannel;
7264 return rc;
7265 }
7266
7267 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
7268 return rc;
7269 }
7270
7271 /*===========================================================================
7272 * FUNCTION : addCallbackChannel
7273 *
7274 * DESCRIPTION: add a callback channel that contains a callback stream
7275 *
7276 * PARAMETERS : none
7277 *
7278 * RETURN : int32_t type of status
7279 * NO_ERROR -- success
7280 * none-zero failure code
7281 *==========================================================================*/
addCallbackChannel()7282 int32_t QCamera2HardwareInterface::addCallbackChannel()
7283 {
7284 int32_t rc = NO_ERROR;
7285 QCameraChannel *pChannel = NULL;
7286
7287 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
7288 delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
7289 m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
7290 }
7291
7292 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
7293 mCameraHandle->ops);
7294 if (NULL == pChannel) {
7295 LOGE("no mem for callback channel");
7296 return NO_MEMORY;
7297 }
7298
7299 rc = pChannel->init(NULL, NULL, this);
7300 if (rc != NO_ERROR) {
7301 LOGE("init callback channel failed, ret = %d",
7302 rc);
7303 delete pChannel;
7304 return rc;
7305 }
7306
7307 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
7308 callback_stream_cb_routine, this);
7309 if (rc != NO_ERROR) {
7310 LOGE("add callback stream failed, ret = %d", rc);
7311 delete pChannel;
7312 return rc;
7313 }
7314
7315 m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
7316 return rc;
7317 }
7318
7319
7320 /*===========================================================================
7321 * FUNCTION : addAnalysisChannel
7322 *
7323 * DESCRIPTION: add a analysis channel that contains a analysis stream
7324 *
7325 * PARAMETERS : none
7326 *
7327 * RETURN : int32_t type of status
7328 * NO_ERROR -- success
7329 * none-zero failure code
7330 *==========================================================================*/
addAnalysisChannel()7331 int32_t QCamera2HardwareInterface::addAnalysisChannel()
7332 {
7333 int32_t rc = NO_ERROR;
7334 QCameraChannel *pChannel = NULL;
7335
7336 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
7337 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
7338 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
7339 }
7340
7341 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
7342 mCameraHandle->ops);
7343 if (NULL == pChannel) {
7344 LOGE("no mem for metadata channel");
7345 return NO_MEMORY;
7346 }
7347
7348 rc = pChannel->init(NULL, NULL, this);
7349 if (rc != NO_ERROR) {
7350 LOGE("init Analysis channel failed, ret = %d", rc);
7351 delete pChannel;
7352 return rc;
7353 }
7354
7355 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7356 NULL, this);
7357 if (rc != NO_ERROR) {
7358 LOGE("add Analysis stream failed, ret = %d", rc);
7359 delete pChannel;
7360 return rc;
7361 }
7362
7363 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
7364 return rc;
7365 }
7366
7367
7368 /*===========================================================================
7369 * FUNCTION : getPPConfig
7370 *
7371 * DESCRIPTION: get Post processing configaration data
7372 *
7373 * PARAMETERS :
7374 * @pp config: pp config structure pointer,
7375 * @curIndex: current pp channel index
7376 * @multipass: Flag if multipass prcessing enabled.
7377 *
7378 * RETURN : int32_t type of status
7379 * NO_ERROR -- success
7380 * none-zero failure code
7381 *==========================================================================*/
getPPConfig(cam_pp_feature_config_t & pp_config,int8_t curIndex,bool multipass)7382 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
7383 int8_t curIndex, bool multipass)
7384 {
7385 int32_t rc = NO_ERROR;
7386
7387 if (multipass) {
7388 LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
7389 mParameters.getReprocCount(), curIndex);
7390 }
7391
7392 LOGH("Supported pproc feature mask = %x",
7393 gCamCapability[mCameraId]->qcom_supported_feature_mask);
7394 uint32_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
7395 int32_t zoomLevel = mParameters.getParmZoomLevel();
7396 uint32_t rotation = mParameters.getJpegRotation();
7397 int32_t effect = mParameters.getEffectValue();
7398
7399 pp_config.cur_reproc_count = curIndex + 1;
7400 pp_config.total_reproc_count = mParameters.getReprocCount();
7401
7402 switch(curIndex) {
7403 case 0:
7404 //Configure feature mask for first pass of reprocessing
7405 //check if any effects are enabled
7406 if ((CAM_EFFECT_MODE_OFF != effect) &&
7407 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
7408 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
7409 pp_config.effect = effect;
7410 }
7411
7412 //check for features that need to be enabled by default like sharpness
7413 //(if supported by hw).
7414 if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
7415 !mParameters.isOptiZoomEnabled()) {
7416 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
7417 pp_config.sharpness = mParameters.getSharpness();
7418 }
7419
7420 //check if zoom is enabled
7421 if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
7422 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
7423 }
7424
7425 if (mParameters.isWNREnabled() &&
7426 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
7427 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
7428 pp_config.denoise2d.denoise_enable = 1;
7429 pp_config.denoise2d.process_plates =
7430 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
7431 }
7432
7433 if (isCACEnabled()) {
7434 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
7435 }
7436
7437 //check if rotation is required
7438 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
7439 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
7440 if (rotation == 0) {
7441 pp_config.rotation = ROTATE_0;
7442 } else if (rotation == 90) {
7443 pp_config.rotation = ROTATE_90;
7444 } else if (rotation == 180) {
7445 pp_config.rotation = ROTATE_180;
7446 } else if (rotation == 270) {
7447 pp_config.rotation = ROTATE_270;
7448 }
7449 }
7450
7451 if (mParameters.isHDREnabled()){
7452 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
7453 pp_config.hdr_param.hdr_enable = 1;
7454 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
7455 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
7456 } else {
7457 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
7458 pp_config.hdr_param.hdr_enable = 0;
7459 }
7460
7461 //check if scaling is enabled
7462 if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
7463 mParameters.isReprocScaleEnabled() &&
7464 mParameters.isUnderReprocScaling()){
7465 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
7466 mParameters.getPicSizeFromAPK(
7467 pp_config.scale_param.output_width,
7468 pp_config.scale_param.output_height);
7469 }
7470
7471 if(mParameters.isUbiFocusEnabled()) {
7472 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
7473 } else {
7474 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
7475 }
7476
7477 if(mParameters.isUbiRefocus()) {
7478 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
7479 pp_config.misc_buf_param.misc_buffer_index = 0;
7480 } else {
7481 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
7482 }
7483
7484 if(mParameters.isChromaFlashEnabled()) {
7485 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
7486 pp_config.flash_value = CAM_FLASH_ON;
7487 } else {
7488 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
7489 }
7490
7491 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
7492 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
7493 pp_config.zoom_level = (uint8_t) zoomLevel;
7494 } else {
7495 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
7496 }
7497
7498 if (mParameters.getofflineRAW()) {
7499 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
7500 }
7501
7502 if (mParameters.isTruePortraitEnabled()) {
7503 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
7504 pp_config.misc_buf_param.misc_buffer_index = 0;
7505 } else {
7506 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
7507 }
7508
7509 if(mParameters.isStillMoreEnabled()) {
7510 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
7511 } else {
7512 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
7513 }
7514
7515 if (mParameters.isOEMFeatEnabled()) {
7516 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
7517 }
7518
7519 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
7520 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
7521 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
7522 } else {
7523 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
7524 }
7525 }
7526
7527 if ((multipass) &&
7528 (m_postprocessor.getPPChannelCount() > 1)) {
7529 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
7530 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
7531 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
7532 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
7533 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
7534 } else {
7535 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
7536 }
7537
7538 cam_dimension_t thumb_src_dim;
7539 cam_dimension_t thumb_dst_dim;
7540 mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
7541 mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
7542 if ((thumb_dst_dim.width != thumb_src_dim.width) ||
7543 (thumb_dst_dim.height != thumb_src_dim.height)) {
7544 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
7545 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
7546 }
7547 }
7548
7549 break;
7550
7551 case 1:
7552 //Configure feature mask for second pass of reprocessing
7553 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
7554 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
7555 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
7556 if (rotation == 0) {
7557 pp_config.rotation = ROTATE_0;
7558 } else if (rotation == 90) {
7559 pp_config.rotation = ROTATE_90;
7560 } else if (rotation == 180) {
7561 pp_config.rotation = ROTATE_180;
7562 } else if (rotation == 270) {
7563 pp_config.rotation = ROTATE_270;
7564 }
7565 }
7566 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
7567 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
7568 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
7569 } else {
7570 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
7571 }
7572 }
7573 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
7574 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
7575 break;
7576
7577 }
7578 LOGH("pproc feature mask set = %x pass count = %d",
7579 pp_config.feature_mask, curIndex);
7580 return rc;
7581 }
7582
7583 /*===========================================================================
7584 * FUNCTION : addReprocChannel
7585 *
7586 * DESCRIPTION: add a reprocess channel that will do reprocess on frames
7587 * coming from input channel
7588 *
7589 * PARAMETERS :
7590 * @pInputChannel : ptr to input channel whose frames will be post-processed
7591 * @cur_channel_index : Current channel index in multipass
7592 *
7593 * RETURN : Ptr to the newly created channel obj. NULL if failed.
7594 *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel,int8_t cur_channel_index)7595 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
7596 QCameraChannel *pInputChannel, int8_t cur_channel_index)
7597 {
7598 int32_t rc = NO_ERROR;
7599 QCameraReprocessChannel *pChannel = NULL;
7600 uint32_t burst_cnt = mParameters.getNumOfSnapshots();
7601
7602 if (pInputChannel == NULL) {
7603 LOGE("input channel obj is NULL");
7604 return NULL;
7605 }
7606
7607 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
7608 mCameraHandle->ops);
7609 if (NULL == pChannel) {
7610 LOGE("no mem for reprocess channel");
7611 return NULL;
7612 }
7613
7614 // Capture channel, only need snapshot and postview streams start together
7615 mm_camera_channel_attr_t attr;
7616 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7617 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7618 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7619 rc = pChannel->init(&attr,
7620 postproc_channel_cb_routine,
7621 this);
7622 if (rc != NO_ERROR) {
7623 LOGE("init reprocess channel failed, ret = %d", rc);
7624 delete pChannel;
7625 return NULL;
7626 }
7627
7628 // pp feature config
7629 cam_pp_feature_config_t pp_config;
7630 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
7631
7632 rc = getPPConfig(pp_config, cur_channel_index,
7633 ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
7634 if (rc != NO_ERROR){
7635 LOGE("Error while creating PP config");
7636 delete pChannel;
7637 return NULL;
7638 }
7639
7640 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
7641
7642 //WNR and HDR happen inline. No extra buffers needed.
7643 uint32_t temp_feature_mask = pp_config.feature_mask;
7644 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
7645 if (temp_feature_mask && mParameters.isHDREnabled()) {
7646 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
7647 }
7648
7649 if (mParameters.isStillMoreEnabled()) {
7650 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
7651 pp_config.burst_cnt = stillmore_config.burst_count;
7652 LOGH("Stillmore burst %d", pp_config.burst_cnt);
7653
7654 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
7655 // number of capture is already added. In the case of liveshot,
7656 // stillmore burst is 1. This is to account for the premature decrement
7657 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
7658 minStreamBufNum += 1;
7659 }
7660 }
7661
7662 if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
7663 minStreamBufNum += mParameters.getReprocCount() - 1;
7664 burst_cnt = mParameters.getReprocCount();
7665 if (cur_channel_index == 0) {
7666 pChannel->setReprocCount(2);
7667 } else {
7668 pChannel->setReprocCount(1);
7669 }
7670 } else {
7671 pChannel->setReprocCount(1);
7672 }
7673
7674 // Add non inplace image lib buffers only when ppproc is present,
7675 // becuase pproc is non inplace and input buffers for img lib
7676 // are output for pproc and this number of extra buffers is required
7677 // If pproc is not there, input buffers for imglib are from snapshot stream
7678 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
7679 if (temp_feature_mask && imglib_extra_bufs) {
7680 // 1 is added because getNumOfExtraBuffersForImageProc returns extra
7681 // buffers assuming number of capture is already added
7682 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
7683 }
7684
7685 //Mask out features that are already processed in snapshot stream.
7686 uint32_t snapshot_feature_mask = 0;
7687 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
7688
7689 pp_config.feature_mask &= ~snapshot_feature_mask;
7690 LOGH("Snapshot feature mask: 0x%x, reproc feature mask: 0x%x",
7691 snapshot_feature_mask, pp_config.feature_mask);
7692
7693 bool offlineReproc = isRegularCapture();
7694 if (m_postprocessor.mOfflineDataBufs != NULL) {
7695 offlineReproc = TRUE;
7696 }
7697
7698 cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
7699 paddingInfo.offset_info.offset_x = 0;
7700 paddingInfo.offset_info.offset_y = 0;
7701 rc = pChannel->addReprocStreamsFromSource(*this,
7702 pp_config,
7703 pInputChannel,
7704 minStreamBufNum,
7705 burst_cnt,
7706 &paddingInfo,
7707 mParameters,
7708 mLongshotEnabled,
7709 offlineReproc);
7710 if (rc != NO_ERROR) {
7711 delete pChannel;
7712 return NULL;
7713 }
7714
7715 return pChannel;
7716 }
7717
7718 /*===========================================================================
7719 * FUNCTION : addOfflineReprocChannel
7720 *
7721 * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
7722 * that will do reprocess on frames coming from external images
7723 *
7724 * PARAMETERS :
7725 * @img_config : offline reporcess image info
7726 * @pp_feature : pp feature config
7727 *
7728 * RETURN : int32_t type of status
7729 * NO_ERROR -- success
7730 * none-zero failure code
7731 *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)7732 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
7733 cam_pp_offline_src_config_t &img_config,
7734 cam_pp_feature_config_t &pp_feature,
7735 stream_cb_routine stream_cb,
7736 void *userdata)
7737 {
7738 int32_t rc = NO_ERROR;
7739 QCameraReprocessChannel *pChannel = NULL;
7740
7741 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
7742 mCameraHandle->ops);
7743 if (NULL == pChannel) {
7744 LOGE("no mem for reprocess channel");
7745 return NULL;
7746 }
7747
7748 rc = pChannel->init(NULL, NULL, NULL);
7749 if (rc != NO_ERROR) {
7750 LOGE("init reprocess channel failed, ret = %d", rc);
7751 delete pChannel;
7752 return NULL;
7753 }
7754
7755 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
7756 if (pStreamInfo == NULL) {
7757 LOGE("no mem for stream info buf");
7758 delete pChannel;
7759 return NULL;
7760 }
7761
7762 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
7763 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
7764 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
7765 streamInfoBuf->fmt = img_config.input_fmt;
7766 streamInfoBuf->dim = img_config.input_dim;
7767 streamInfoBuf->buf_planes = img_config.input_buf_planes;
7768 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
7769 streamInfoBuf->num_of_burst = img_config.num_of_bufs;
7770
7771 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
7772 streamInfoBuf->reprocess_config.offline = img_config;
7773 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
7774
7775 rc = pChannel->addStream(*this,
7776 pStreamInfo, NULL, img_config.num_of_bufs,
7777 &gCamCapability[mCameraId]->padding_info,
7778 stream_cb, userdata, false);
7779
7780 if (rc != NO_ERROR) {
7781 LOGE("add reprocess stream failed, ret = %d", rc);
7782 delete pChannel;
7783 return NULL;
7784 }
7785
7786 return pChannel;
7787 }
7788
7789 /*===========================================================================
7790 * FUNCTION : addChannel
7791 *
7792 * DESCRIPTION: add a channel by its type
7793 *
7794 * PARAMETERS :
7795 * @ch_type : channel type
7796 *
7797 * RETURN : int32_t type of status
7798 * NO_ERROR -- success
7799 * none-zero failure code
7800 *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)7801 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
7802 {
7803 int32_t rc = UNKNOWN_ERROR;
7804 switch (ch_type) {
7805 case QCAMERA_CH_TYPE_ZSL:
7806 rc = addZSLChannel();
7807 break;
7808 case QCAMERA_CH_TYPE_CAPTURE:
7809 rc = addCaptureChannel();
7810 break;
7811 case QCAMERA_CH_TYPE_PREVIEW:
7812 rc = addPreviewChannel();
7813 break;
7814 case QCAMERA_CH_TYPE_VIDEO:
7815 rc = addVideoChannel();
7816 break;
7817 case QCAMERA_CH_TYPE_SNAPSHOT:
7818 rc = addSnapshotChannel();
7819 break;
7820 case QCAMERA_CH_TYPE_RAW:
7821 rc = addRawChannel();
7822 break;
7823 case QCAMERA_CH_TYPE_METADATA:
7824 rc = addMetaDataChannel();
7825 break;
7826 case QCAMERA_CH_TYPE_CALLBACK:
7827 rc = addCallbackChannel();
7828 break;
7829 case QCAMERA_CH_TYPE_ANALYSIS:
7830 rc = addAnalysisChannel();
7831 break;
7832 default:
7833 break;
7834 }
7835 return rc;
7836 }
7837
7838 /*===========================================================================
7839 * FUNCTION : delChannel
7840 *
7841 * DESCRIPTION: delete a channel by its type
7842 *
7843 * PARAMETERS :
7844 * @ch_type : channel type
7845 * @destroy : delete context as well
7846 *
7847 * RETURN : int32_t type of status
7848 * NO_ERROR -- success
7849 * none-zero failure code
7850 *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)7851 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
7852 bool destroy)
7853 {
7854 if (m_channels[ch_type] != NULL) {
7855 if (destroy) {
7856 delete m_channels[ch_type];
7857 m_channels[ch_type] = NULL;
7858 } else {
7859 m_channels[ch_type]->deleteChannel();
7860 }
7861 }
7862
7863 return NO_ERROR;
7864 }
7865
7866 /*===========================================================================
7867 * FUNCTION : startChannel
7868 *
7869 * DESCRIPTION: start a channel by its type
7870 *
7871 * PARAMETERS :
7872 * @ch_type : channel type
7873 *
7874 * RETURN : int32_t type of status
7875 * NO_ERROR -- success
7876 * none-zero failure code
7877 *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)7878 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
7879 {
7880 int32_t rc = UNKNOWN_ERROR;
7881 if (m_channels[ch_type] != NULL) {
7882 rc = m_channels[ch_type]->start();
7883 }
7884 return rc;
7885 }
7886
7887 /*===========================================================================
7888 * FUNCTION : stopChannel
7889 *
7890 * DESCRIPTION: stop a channel by its type
7891 *
7892 * PARAMETERS :
7893 * @ch_type : channel type
7894 *
7895 * RETURN : int32_t type of status
7896 * NO_ERROR -- success
7897 * none-zero failure code
7898 *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)7899 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
7900 {
7901 int32_t rc = UNKNOWN_ERROR;
7902 if (m_channels[ch_type] != NULL) {
7903 rc = m_channels[ch_type]->stop();
7904 }
7905
7906 return rc;
7907 }
7908
7909 /*===========================================================================
7910 * FUNCTION : preparePreview
7911 *
7912 * DESCRIPTION: add channels needed for preview
7913 *
7914 * PARAMETERS : none
7915 *
7916 * RETURN : int32_t type of status
7917 * NO_ERROR -- success
7918 * none-zero failure code
7919 *==========================================================================*/
preparePreview()7920 int32_t QCamera2HardwareInterface::preparePreview()
7921 {
7922 ATRACE_CALL();
7923 int32_t rc = NO_ERROR;
7924
7925 LOGI("E");
7926 rc = mParameters.setStreamConfigure(false, false, false);
7927 if (rc != NO_ERROR) {
7928 LOGE("setStreamConfigure failed %d", rc);
7929 return rc;
7930 }
7931
7932 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
7933 rc = addChannel(QCAMERA_CH_TYPE_ZSL);
7934 if (rc != NO_ERROR) {
7935 LOGE("failed!! rc = %d", rc);
7936 return rc;
7937 }
7938
7939 if (mParameters.isUBWCEnabled()) {
7940 cam_format_t fmt;
7941 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
7942 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
7943 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
7944 if (rc != NO_ERROR) {
7945 delChannel(QCAMERA_CH_TYPE_ZSL);
7946 LOGE("failed!! rc = %d", rc);
7947 return rc;
7948 }
7949 }
7950 }
7951
7952 if (mParameters.getofflineRAW()) {
7953 addChannel(QCAMERA_CH_TYPE_RAW);
7954 }
7955 } else {
7956 bool recordingHint = mParameters.getRecordingHintValue();
7957 if(!isRdiMode() && recordingHint) {
7958 //stop face detection,longshot,etc if turned ON in Camera mode
7959 #ifndef VANILLA_HAL
7960 int32_t arg; //dummy arg
7961 if (isLongshotEnabled()) {
7962 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
7963 }
7964 if (mParameters.isFaceDetectionEnabled()
7965 && (!mParameters.fdModeInVideo())) {
7966 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
7967 }
7968 if (mParameters.isHistogramEnabled()) {
7969 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
7970 }
7971 #endif
7972 //Don't create snapshot channel for liveshot, if low power mode is set.
7973 //Use video stream instead.
7974 if (!isLowPowerMode()) {
7975 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7976 if (rc != NO_ERROR) {
7977 return rc;
7978 }
7979 }
7980
7981 rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
7982 if (rc != NO_ERROR) {
7983 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7984 LOGE("failed!! rc = %d", rc);
7985 return rc;
7986 }
7987 }
7988
7989 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
7990 if (!isRdiMode() && (rc != NO_ERROR)) {
7991 if (recordingHint) {
7992 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7993 delChannel(QCAMERA_CH_TYPE_VIDEO);
7994 }
7995 }
7996
7997 if (mParameters.isUBWCEnabled() && !recordingHint) {
7998 cam_format_t fmt;
7999 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8000 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8001 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8002 if (rc != NO_ERROR) {
8003 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8004 if (!isRdiMode()) {
8005 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8006 delChannel(QCAMERA_CH_TYPE_VIDEO);
8007 }
8008 LOGE("failed!! rc = %d", rc);
8009 return rc;
8010 }
8011 }
8012 }
8013
8014 if (NO_ERROR != rc) {
8015 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8016 LOGE("failed!! rc = %d", rc);
8017 }
8018 }
8019
8020 LOGI("E rc = %d", rc);
8021 return rc;
8022 }
8023
8024 /*===========================================================================
8025 * FUNCTION : unpreparePreview
8026 *
8027 * DESCRIPTION: delete channels for preview
8028 *
8029 * PARAMETERS : none
8030 *
8031 * RETURN : none
8032 *==========================================================================*/
unpreparePreview()8033 void QCamera2HardwareInterface::unpreparePreview()
8034 {
8035 delChannel(QCAMERA_CH_TYPE_ZSL);
8036 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8037 delChannel(QCAMERA_CH_TYPE_VIDEO);
8038 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8039 delChannel(QCAMERA_CH_TYPE_CALLBACK);
8040 delChannel(QCAMERA_CH_TYPE_RAW);
8041 }
8042
8043 /*===========================================================================
8044 * FUNCTION : playShutter
8045 *
8046 * DESCRIPTION: send request to play shutter sound
8047 *
8048 * PARAMETERS : none
8049 *
8050 * RETURN : none
8051 *==========================================================================*/
playShutter()8052 void QCamera2HardwareInterface::playShutter(){
8053 if (mNotifyCb == NULL ||
8054 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
8055 LOGD("shutter msg not enabled or NULL cb");
8056 return;
8057 }
8058 LOGH("CAMERA_MSG_SHUTTER ");
8059 qcamera_callback_argm_t cbArg;
8060 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8061 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
8062 cbArg.msg_type = CAMERA_MSG_SHUTTER;
8063 cbArg.ext1 = 0;
8064 cbArg.ext2 = false;
8065 m_cbNotifier.notifyCallback(cbArg);
8066 }
8067
8068 /*===========================================================================
8069 * FUNCTION : getChannelByHandle
8070 *
8071 * DESCRIPTION: return a channel by its handle
8072 *
8073 * PARAMETERS :
8074 * @channelHandle : channel handle
8075 *
8076 * RETURN : a channel obj if found, NULL if not found
8077 *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)8078 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
8079 {
8080 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
8081 if (m_channels[i] != NULL &&
8082 m_channels[i]->getMyHandle() == channelHandle) {
8083 return m_channels[i];
8084 }
8085 }
8086
8087 return NULL;
8088 }
8089 /*===========================================================================
8090 * FUNCTION : needPreviewFDCallback
8091 *
8092 * DESCRIPTION: decides if needPreviewFDCallback
8093 *
8094 * PARAMETERS :
8095 * @num_faces : number of faces
8096 *
8097 * RETURN : bool type of status
8098 * true -- success
8099 * fale -- failure code
8100 *==========================================================================*/
needPreviewFDCallback(uint8_t num_faces)8101 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
8102 {
8103 if (num_faces == 0 && mNumPreviewFaces == 0) {
8104 return false;
8105 }
8106
8107 return true;
8108 }
8109
8110 /*===========================================================================
8111 * FUNCTION : processFaceDetectionReuslt
8112 *
8113 * DESCRIPTION: process face detection reuslt
8114 *
8115 * PARAMETERS :
8116 * @faces_data : ptr to face processing result struct
8117 *
8118 * RETURN : int32_t type of status
8119 * NO_ERROR -- success
8120 * none-zero failure code
8121 *==========================================================================*/
processFaceDetectionResult(cam_faces_data_t * faces_data)8122 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
8123 {
8124 if (!mParameters.isFaceDetectionEnabled()) {
8125 LOGH("FaceDetection not enabled, no ops here");
8126 return NO_ERROR;
8127 }
8128
8129 qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
8130 cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
8131 if ((NULL == mDataCb) ||
8132 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
8133 (!needPreviewFDCallback(detect_data->num_faces_detected))
8134 #ifndef VANILLA_HAL
8135 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
8136 #endif
8137 ) {
8138 LOGH("metadata msgtype not enabled, no ops here");
8139 return NO_ERROR;
8140 }
8141
8142 if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
8143 // Don't send callback to app if this is skipped by fd at backend
8144 return NO_ERROR;
8145 }
8146
8147 cam_dimension_t display_dim;
8148 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
8149 if (display_dim.width <= 0 || display_dim.height <= 0) {
8150 LOGE("Invalid preview width or height (%d x %d)",
8151 display_dim.width, display_dim.height);
8152 return UNKNOWN_ERROR;
8153 }
8154
8155 // process face detection result
8156 // need separate face detection in preview or snapshot type
8157 size_t faceResultSize = 0;
8158 size_t data_len = 0;
8159 if(fd_type == QCAMERA_FD_PREVIEW){
8160 //fd for preview frames
8161 faceResultSize = sizeof(camera_frame_metadata_t);
8162 faceResultSize += sizeof(camera_face_t) * MAX_ROI;
8163 }else if(fd_type == QCAMERA_FD_SNAPSHOT){
8164 #ifndef VANILLA_HAL
8165 // fd for snapshot frames
8166 //check if face is detected in this frame
8167 if(detect_data->num_faces_detected > 0){
8168 data_len = sizeof(camera_frame_metadata_t) +
8169 sizeof(camera_face_t) * detect_data->num_faces_detected;
8170 }else{
8171 //no face
8172 data_len = 0;
8173 }
8174 #endif
8175 faceResultSize = 1 *sizeof(int) //meta data type
8176 + 1 *sizeof(int) // meta data len
8177 + data_len; //data
8178 }
8179
8180 camera_memory_t *faceResultBuffer = mGetMemory(-1,
8181 faceResultSize,
8182 1,
8183 mCallbackCookie);
8184 if ( NULL == faceResultBuffer ) {
8185 LOGE("Not enough memory for face result data");
8186 return NO_MEMORY;
8187 }
8188
8189 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
8190 memset(pFaceResult, 0, faceResultSize);
8191 unsigned char *faceData = NULL;
8192 if(fd_type == QCAMERA_FD_PREVIEW){
8193 faceData = pFaceResult;
8194 mNumPreviewFaces = detect_data->num_faces_detected;
8195 }else if(fd_type == QCAMERA_FD_SNAPSHOT){
8196 #ifndef VANILLA_HAL
8197 //need fill meta type and meta data len first
8198 int *data_header = (int* )pFaceResult;
8199 data_header[0] = CAMERA_META_DATA_FD;
8200 data_header[1] = (int)data_len;
8201
8202 if(data_len <= 0){
8203 //if face is not valid or do not have face, return
8204 qcamera_callback_argm_t cbArg;
8205 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8206 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
8207 cbArg.msg_type = CAMERA_MSG_META_DATA;
8208 cbArg.data = faceResultBuffer;
8209 cbArg.user_data = faceResultBuffer;
8210 cbArg.cookie = this;
8211 cbArg.release_cb = releaseCameraMemory;
8212 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
8213 if (rc != NO_ERROR) {
8214 LOGE("fail sending notification");
8215 faceResultBuffer->release(faceResultBuffer);
8216 }
8217 return rc;
8218 }
8219 #endif
8220 faceData = pFaceResult + 2 *sizeof(int); //skip two int length
8221 }
8222
8223 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
8224 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
8225
8226 roiData->number_of_faces = detect_data->num_faces_detected;
8227 roiData->faces = faces;
8228 if (roiData->number_of_faces > 0) {
8229 for (int i = 0; i < roiData->number_of_faces; i++) {
8230 faces[i].id = detect_data->faces[i].face_id;
8231 faces[i].score = detect_data->faces[i].score;
8232
8233 // left
8234 faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
8235 detect_data->faces[i].face_boundary.left,
8236 display_dim.width, 2000, -1000);
8237
8238 // top
8239 faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
8240 detect_data->faces[i].face_boundary.top,
8241 display_dim.height, 2000, -1000);
8242
8243 // right
8244 faces[i].rect[2] = faces[i].rect[0] +
8245 MAP_TO_DRIVER_COORDINATE(
8246 detect_data->faces[i].face_boundary.width,
8247 display_dim.width, 2000, 0);
8248
8249 // bottom
8250 faces[i].rect[3] = faces[i].rect[1] +
8251 MAP_TO_DRIVER_COORDINATE(
8252 detect_data->faces[i].face_boundary.height,
8253 display_dim.height, 2000, 0);
8254
8255 if (faces_data->landmark_valid) {
8256 // Center of left eye
8257 faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
8258 faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
8259 display_dim.width, 2000, -1000);
8260 faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
8261 faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
8262 display_dim.height, 2000, -1000);
8263
8264 // Center of right eye
8265 faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
8266 faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
8267 display_dim.width, 2000, -1000);
8268 faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
8269 faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
8270 display_dim.height, 2000, -1000);
8271
8272 // Center of mouth
8273 faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
8274 faces_data->landmark_data.face_landmarks[i].mouth_center.x,
8275 display_dim.width, 2000, -1000);
8276 faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
8277 faces_data->landmark_data.face_landmarks[i].mouth_center.y,
8278 display_dim.height, 2000, -1000);
8279 } else {
8280 // return -2000 if invalid
8281 faces[i].left_eye[0] = -2000;
8282 faces[i].left_eye[1] = -2000;
8283
8284 faces[i].right_eye[0] = -2000;
8285 faces[i].right_eye[1] = -2000;
8286
8287 faces[i].mouth[0] = -2000;
8288 faces[i].mouth[1] = -2000;
8289 }
8290
8291 #ifndef VANILLA_HAL
8292 #ifdef TARGET_TS_MAKEUP
8293 mFaceRect.left = detect_data->faces[i].face_boundary.left;
8294 mFaceRect.top = detect_data->faces[i].face_boundary.top;
8295 mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
8296 mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
8297 #endif
8298 if (faces_data->smile_valid) {
8299 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
8300 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
8301 }
8302 if (faces_data->blink_valid) {
8303 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
8304 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
8305 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
8306 }
8307 if (faces_data->recog_valid) {
8308 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
8309 }
8310 if (faces_data->gaze_valid) {
8311 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
8312 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
8313 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
8314 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
8315 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
8316 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
8317 }
8318 #endif
8319
8320 }
8321 }
8322 else{
8323 #ifdef TARGET_TS_MAKEUP
8324 memset(&mFaceRect,-1,sizeof(mFaceRect));
8325 #endif
8326 }
8327 qcamera_callback_argm_t cbArg;
8328 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8329 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
8330 if(fd_type == QCAMERA_FD_PREVIEW){
8331 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
8332 }
8333 #ifndef VANILLA_HAL
8334 else if(fd_type == QCAMERA_FD_SNAPSHOT){
8335 cbArg.msg_type = CAMERA_MSG_META_DATA;
8336 }
8337 #endif
8338 cbArg.data = faceResultBuffer;
8339 cbArg.metadata = roiData;
8340 cbArg.user_data = faceResultBuffer;
8341 cbArg.cookie = this;
8342 cbArg.release_cb = releaseCameraMemory;
8343 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
8344 if (rc != NO_ERROR) {
8345 LOGE("fail sending notification");
8346 faceResultBuffer->release(faceResultBuffer);
8347 }
8348
8349 return rc;
8350 }
8351
8352 /*===========================================================================
8353 * FUNCTION : releaseCameraMemory
8354 *
8355 * DESCRIPTION: releases camera memory objects
8356 *
8357 * PARAMETERS :
8358 * @data : buffer to be released
8359 * @cookie : context data
8360 * @cbStatus: callback status
8361 *
8362 * RETURN : None
8363 *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)8364 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
8365 void */*cookie*/,
8366 int32_t /*cbStatus*/)
8367 {
8368 camera_memory_t *mem = ( camera_memory_t * ) data;
8369 if ( NULL != mem ) {
8370 mem->release(mem);
8371 }
8372 }
8373
8374 /*===========================================================================
8375 * FUNCTION : returnStreamBuffer
8376 *
8377 * DESCRIPTION: returns back a stream buffer
8378 *
8379 * PARAMETERS :
8380 * @data : buffer to be released
8381 * @cookie : context data
8382 * @cbStatus: callback status
8383 *
8384 * RETURN : None
8385 *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)8386 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
8387 void *cookie,
8388 int32_t /*cbStatus*/)
8389 {
8390 QCameraStream *stream = ( QCameraStream * ) cookie;
8391 int idx = *((int *)data);
8392 if ((NULL != stream) && (0 <= idx)) {
8393 stream->bufDone((uint32_t)idx);
8394 } else {
8395 LOGE("Cannot return buffer %d %p", idx, cookie);
8396 }
8397 }
8398
8399 /*===========================================================================
8400 * FUNCTION : processHistogramStats
8401 *
8402 * DESCRIPTION: process histogram stats
8403 *
8404 * PARAMETERS :
8405 * @hist_data : ptr to histogram stats struct
8406 *
8407 * RETURN : int32_t type of status
8408 * NO_ERROR -- success
8409 * none-zero failure code
8410 *==========================================================================*/
processHistogramStats(__unused cam_hist_stats_t & stats_data)8411 int32_t QCamera2HardwareInterface::processHistogramStats(
8412 __unused cam_hist_stats_t &stats_data)
8413 {
8414 #ifndef VANILLA_HAL
8415 if (!mParameters.isHistogramEnabled()) {
8416 LOGH("Histogram not enabled, no ops here");
8417 return NO_ERROR;
8418 }
8419
8420 camera_memory_t *histBuffer = mGetMemory(-1,
8421 sizeof(cam_histogram_data_t),
8422 1,
8423 mCallbackCookie);
8424 if ( NULL == histBuffer ) {
8425 LOGE("Not enough memory for histogram data");
8426 return NO_MEMORY;
8427 }
8428
8429 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
8430 if (pHistData == NULL) {
8431 LOGE("memory data ptr is NULL");
8432 return UNKNOWN_ERROR;
8433 }
8434
8435 switch (stats_data.type) {
8436 case CAM_HISTOGRAM_TYPE_BAYER:
8437 *pHistData = stats_data.bayer_stats.gb_stats;
8438 break;
8439 case CAM_HISTOGRAM_TYPE_YUV:
8440 *pHistData = stats_data.yuv_stats;
8441 break;
8442 }
8443
8444 qcamera_callback_argm_t cbArg;
8445 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
8446 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
8447 cbArg.msg_type = CAMERA_MSG_STATS_DATA;
8448 cbArg.data = histBuffer;
8449 cbArg.user_data = histBuffer;
8450 cbArg.cookie = this;
8451 cbArg.release_cb = releaseCameraMemory;
8452 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
8453 if (rc != NO_ERROR) {
8454 LOGE("fail sending notification");
8455 histBuffer->release(histBuffer);
8456 }
8457 #endif
8458 return NO_ERROR;
8459 }
8460
8461 /*===========================================================================
8462 * FUNCTION : calcThermalLevel
8463 *
8464 * DESCRIPTION: Calculates the target fps range depending on
8465 * the thermal level.
8466 * Note that this function can be called from QCameraParametersIntf
8467 * while mutex is held. So it should not call back into
8468 * QCameraParametersIntf causing deadlock.
8469 *
8470 * PARAMETERS :
8471 * @level : received thermal level
8472 * @minFPS : minimum configured fps range
8473 * @maxFPS : maximum configured fps range
8474 * @minVideoFps: minimum configured fps range
8475 * @maxVideoFps: maximum configured fps range
8476 * @adjustedRange : target fps range
8477 * @skipPattern : target skip pattern
8478 *
8479 * RETURN : int32_t type of status
8480 * NO_ERROR -- success
8481 * none-zero failure code
8482 *==========================================================================*/
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)8483 int QCamera2HardwareInterface::calcThermalLevel(
8484 qcamera_thermal_level_enum_t level,
8485 const int minFPSi,
8486 const int maxFPSi,
8487 const float &minVideoFps,
8488 const float &maxVideoFps,
8489 cam_fps_range_t &adjustedRange,
8490 enum msm_vfe_frame_skip_pattern &skipPattern)
8491 {
8492 const float minFPS = (float)minFPSi;
8493 const float maxFPS = (float)maxFPSi;
8494
8495 LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
8496 "video minfps %f, video maxfpS %f",
8497 level, minFPS, maxFPS, minVideoFps, maxVideoFps);
8498
8499 switch(level) {
8500 case QCAMERA_THERMAL_NO_ADJUSTMENT:
8501 {
8502 adjustedRange.min_fps = minFPS / 1000.0f;
8503 adjustedRange.max_fps = maxFPS / 1000.0f;
8504 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
8505 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
8506 skipPattern = NO_SKIP;
8507 }
8508 break;
8509 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
8510 {
8511 adjustedRange.min_fps = minFPS / 1000.0f;
8512 adjustedRange.max_fps = maxFPS / 1000.0f;
8513 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
8514 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
8515 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
8516 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
8517 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
8518 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
8519 if ( adjustedRange.min_fps < 1 ) {
8520 adjustedRange.min_fps = 1;
8521 }
8522 if ( adjustedRange.max_fps < 1 ) {
8523 adjustedRange.max_fps = 1;
8524 }
8525 if ( adjustedRange.video_min_fps < 1 ) {
8526 adjustedRange.video_min_fps = 1;
8527 }
8528 if ( adjustedRange.video_max_fps < 1 ) {
8529 adjustedRange.video_max_fps = 1;
8530 }
8531 skipPattern = EVERY_2FRAME;
8532 }
8533 break;
8534 case QCAMERA_THERMAL_BIG_ADJUSTMENT:
8535 {
8536 adjustedRange.min_fps = minFPS / 1000.0f;
8537 adjustedRange.max_fps = maxFPS / 1000.0f;
8538 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
8539 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
8540 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
8541 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
8542 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
8543 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
8544 if ( adjustedRange.min_fps < 1 ) {
8545 adjustedRange.min_fps = 1;
8546 }
8547 if ( adjustedRange.max_fps < 1 ) {
8548 adjustedRange.max_fps = 1;
8549 }
8550 if ( adjustedRange.video_min_fps < 1 ) {
8551 adjustedRange.video_min_fps = 1;
8552 }
8553 if ( adjustedRange.video_max_fps < 1 ) {
8554 adjustedRange.video_max_fps = 1;
8555 }
8556 skipPattern = EVERY_4FRAME;
8557 }
8558 break;
8559 case QCAMERA_THERMAL_MAX_ADJUSTMENT:
8560 {
8561 // Stop Preview?
8562 // Set lowest min FPS for now
8563 adjustedRange.min_fps = minFPS/1000.0f;
8564 adjustedRange.max_fps = minFPS/1000.0f;
8565 cam_capability_t *capability = gCamCapability[mCameraId];
8566 for (size_t i = 0;
8567 i < capability->fps_ranges_tbl_cnt;
8568 i++) {
8569 if (capability->fps_ranges_tbl[i].min_fps <
8570 adjustedRange.min_fps) {
8571 adjustedRange.min_fps =
8572 capability->fps_ranges_tbl[i].min_fps;
8573 adjustedRange.max_fps = adjustedRange.min_fps;
8574 }
8575 }
8576 skipPattern = MAX_SKIP;
8577 adjustedRange.video_min_fps = adjustedRange.min_fps;
8578 adjustedRange.video_max_fps = adjustedRange.max_fps;
8579 }
8580 break;
8581 case QCAMERA_THERMAL_SHUTDOWN:
8582 {
8583 // send error notify
8584 LOGE("Received shutdown thermal level. Closing camera");
8585 sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
8586 }
8587 break;
8588 default:
8589 {
8590 LOGW("Invalid thermal level %d", level);
8591 return BAD_VALUE;
8592 }
8593 break;
8594 }
8595
8596 return NO_ERROR;
8597 }
8598
8599 /*===========================================================================
8600 * FUNCTION : recalcFPSRange
8601 *
8602 * DESCRIPTION: adjust the configured fps range regarding
8603 * the last thermal level.
8604 *
8605 * PARAMETERS :
8606 * @minFPS : minimum configured fps range
8607 * @maxFPS : maximum configured fps range
8608 * @minVideoFPS : minimum configured video fps
8609 * @maxVideoFPS : maximum configured video fps
8610 * @adjustedRange : target fps range
8611 *
8612 * RETURN : int32_t type of status
8613 * NO_ERROR -- success
8614 * none-zero failure code
8615 *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,const float & minVideoFPS,const float & maxVideoFPS,cam_fps_range_t & adjustedRange)8616 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
8617 const float &minVideoFPS, const float &maxVideoFPS,
8618 cam_fps_range_t &adjustedRange)
8619 {
8620 enum msm_vfe_frame_skip_pattern skipPattern;
8621 calcThermalLevel(mThermalLevel,
8622 minFPS,
8623 maxFPS,
8624 minVideoFPS,
8625 maxVideoFPS,
8626 adjustedRange,
8627 skipPattern);
8628 return NO_ERROR;
8629 }
8630
8631 /*===========================================================================
8632 * FUNCTION : updateThermalLevel
8633 *
8634 * DESCRIPTION: update thermal level depending on thermal events
8635 *
8636 * PARAMETERS :
8637 * @level : thermal level
8638 *
8639 * RETURN : int32_t type of status
8640 * NO_ERROR -- success
8641 * none-zero failure code
8642 *==========================================================================*/
updateThermalLevel(void * thermal_level)8643 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
8644 {
8645 int ret = NO_ERROR;
8646 cam_fps_range_t adjustedRange;
8647 int minFPS, maxFPS;
8648 float minVideoFPS, maxVideoFPS;
8649 enum msm_vfe_frame_skip_pattern skipPattern;
8650 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
8651
8652
8653 if (!mCameraOpened) {
8654 LOGH("Camera is not opened, no need to update camera parameters");
8655 return NO_ERROR;
8656 }
8657 if (mParameters.getRecordingHintValue()) {
8658 LOGH("Thermal mitigation isn't enabled in camcorder mode");
8659 return NO_ERROR;
8660 }
8661
8662 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
8663 qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
8664 if (mParameters.isHfrMode()) {
8665 cam_fps_range_t hfrFpsRange;
8666 mParameters.getHfrFps(hfrFpsRange);
8667 minVideoFPS = hfrFpsRange.video_min_fps;
8668 maxVideoFPS = hfrFpsRange.video_max_fps;
8669 } else {
8670 minVideoFPS = minFPS;
8671 maxVideoFPS = maxFPS;
8672 }
8673
8674 calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
8675 adjustedRange, skipPattern);
8676 mThermalLevel = level;
8677
8678 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
8679 ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
8680 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
8681 ret = mParameters.setFrameSkip(skipPattern);
8682 else
8683 LOGW("Incorrect thermal mode %d", thermalMode);
8684
8685 return ret;
8686
8687 }
8688
8689 /*===========================================================================
8690 * FUNCTION : updateParameters
8691 *
8692 * DESCRIPTION: update parameters
8693 *
8694 * PARAMETERS :
8695 * @parms : input parameters string
8696 * @needRestart : output, flag to indicate if preview restart is needed
8697 *
8698 * RETURN : int32_t type of status
8699 * NO_ERROR -- success
8700 * none-zero failure code
8701 *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)8702 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
8703 {
8704 int rc = NO_ERROR;
8705
8706 String8 str = String8(parms);
8707 rc = mParameters.updateParameters(str, needRestart);
8708 setNeedRestart(needRestart);
8709
8710 // update stream based parameter settings
8711 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
8712 if (m_channels[i] != NULL) {
8713 m_channels[i]->UpdateStreamBasedParameters(mParameters);
8714 }
8715 }
8716
8717 return rc;
8718 }
8719
8720 /*===========================================================================
8721 * FUNCTION : commitParameterChanges
8722 *
8723 * DESCRIPTION: commit parameter changes to the backend to take effect
8724 *
8725 * PARAMETERS : none
8726 *
8727 * RETURN : int32_t type of status
8728 * NO_ERROR -- success
8729 * none-zero failure code
8730 * NOTE : This function must be called after updateParameters.
8731 * Otherwise, no change will be passed to backend to take effect.
8732 *==========================================================================*/
commitParameterChanges()8733 int QCamera2HardwareInterface::commitParameterChanges()
8734 {
8735 int rc = NO_ERROR;
8736 rc = mParameters.commitParameters();
8737 if (rc == NO_ERROR) {
8738 // update number of snapshot based on committed parameters setting
8739 rc = mParameters.setNumOfSnapshot();
8740 }
8741 return rc;
8742 }
8743
8744 /*===========================================================================
8745 * FUNCTION : needDebugFps
8746 *
8747 * DESCRIPTION: if fps log info need to be printed out
8748 *
8749 * PARAMETERS : none
8750 *
8751 * RETURN : true: need print out fps log
8752 * false: no need to print out fps log
8753 *==========================================================================*/
needDebugFps()8754 bool QCamera2HardwareInterface::needDebugFps()
8755 {
8756 bool needFps = false;
8757 needFps = mParameters.isFpsDebugEnabled();
8758 return needFps;
8759 }
8760
8761 /*===========================================================================
8762 * FUNCTION : isCACEnabled
8763 *
8764 * DESCRIPTION: if CAC is enabled
8765 *
8766 * PARAMETERS : none
8767 *
8768 * RETURN : true: needed
8769 * false: no need
8770 *==========================================================================*/
isCACEnabled()8771 bool QCamera2HardwareInterface::isCACEnabled()
8772 {
8773 char prop[PROPERTY_VALUE_MAX];
8774 memset(prop, 0, sizeof(prop));
8775 property_get("persist.camera.feature.cac", prop, "0");
8776 int enableCAC = atoi(prop);
8777 return enableCAC == 1;
8778 }
8779
8780 /*===========================================================================
8781 * FUNCTION : is4k2kResolution
8782 *
8783 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
8784 *
8785 * PARAMETERS : none
8786 *
8787 * RETURN : true: needed
8788 * false: no need
8789 *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)8790 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
8791 {
8792 bool enabled = false;
8793 if ((resolution->width == 4096 && resolution->height == 2160) ||
8794 (resolution->width == 3840 && resolution->height == 2160) ) {
8795 enabled = true;
8796 }
8797 return enabled;
8798 }
8799
8800 /*===========================================================================
8801 * FUNCTION : isPreviewRestartEnabled
8802 *
8803 * DESCRIPTION: Check whether preview should be restarted automatically
8804 * during image capture.
8805 *
8806 * PARAMETERS : none
8807 *
8808 * RETURN : true: needed
8809 * false: no need
8810 *==========================================================================*/
isPreviewRestartEnabled()8811 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
8812 {
8813 char prop[PROPERTY_VALUE_MAX];
8814 memset(prop, 0, sizeof(prop));
8815 property_get("persist.camera.feature.restart", prop, "0");
8816 int earlyRestart = atoi(prop);
8817 return earlyRestart == 1;
8818 }
8819
8820 /*===========================================================================
8821 * FUNCTION : needReprocess
8822 *
8823 * DESCRIPTION: if reprocess is needed
8824 *
8825 * PARAMETERS : none
8826 *
8827 * RETURN : true: needed
8828 * false: no need
8829 *==========================================================================*/
needReprocess()8830 bool QCamera2HardwareInterface::needReprocess()
8831 {
8832 bool needReprocess = false;
8833
8834 if (!mParameters.isJpegPictureFormat() &&
8835 !mParameters.isNV21PictureFormat()) {
8836 // RAW image, no need to reprocess
8837 return false;
8838 }
8839
8840 //Disable reprocess for 4K liveshot case but enable if lowpower mode
8841 if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
8842 && !isLowPowerMode()) {
8843 return false;
8844 }
8845
8846 // pp feature config
8847 cam_pp_feature_config_t pp_config;
8848 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
8849
8850 //Decide whether to do reprocess or not based on
8851 //ppconfig obtained in the first pass.
8852 getPPConfig(pp_config);
8853
8854 if (pp_config.feature_mask > 0) {
8855 needReprocess = true;
8856 }
8857
8858 LOGH("needReprocess %s", needReprocess ? "true" : "false");
8859 return needReprocess;
8860 }
8861
8862
8863 /*===========================================================================
8864 * FUNCTION : needRotationReprocess
8865 *
8866 * DESCRIPTION: if rotation needs to be done by reprocess in pp
8867 *
8868 * PARAMETERS : none
8869 *
8870 * RETURN : true: needed
8871 * false: no need
8872 *==========================================================================*/
needRotationReprocess()8873 bool QCamera2HardwareInterface::needRotationReprocess()
8874 {
8875 if (!mParameters.isJpegPictureFormat() &&
8876 !mParameters.isNV21PictureFormat()) {
8877 // RAW image, no need to reprocess
8878 return false;
8879 }
8880
8881 //Disable reprocess for 4K liveshot case
8882 if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
8883 && !isLowPowerMode()) {
8884 //Disable reprocess for 4K liveshot case
8885 return false;
8886 }
8887
8888 if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
8889 CAM_QCOM_FEATURE_ROTATION) > 0 &&
8890 (mParameters.getJpegRotation() > 0)) {
8891 // current rotation is not zero, and pp has the capability to process rotation
8892 LOGH("need to do reprocess for rotation=%d",
8893 mParameters.getJpegRotation());
8894 return true;
8895 }
8896
8897 return false;
8898 }
8899
8900 /*===========================================================================
8901 * FUNCTION : getThumbnailSize
8902 *
8903 * DESCRIPTION: get user set thumbnail size
8904 *
8905 * PARAMETERS :
8906 * @dim : output of thumbnail dimension
8907 *
8908 * RETURN : none
8909 *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)8910 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
8911 {
8912 mParameters.getThumbnailSize(&dim.width, &dim.height);
8913 }
8914
8915 /*===========================================================================
8916 * FUNCTION : getJpegQuality
8917 *
8918 * DESCRIPTION: get user set jpeg quality
8919 *
8920 * PARAMETERS : none
8921 *
8922 * RETURN : jpeg quality setting
8923 *==========================================================================*/
getJpegQuality()8924 uint32_t QCamera2HardwareInterface::getJpegQuality()
8925 {
8926 uint32_t quality = 0;
8927 quality = mParameters.getJpegQuality();
8928 return quality;
8929 }
8930
8931 /*===========================================================================
8932 * FUNCTION : getExifData
8933 *
8934 * DESCRIPTION: get exif data to be passed into jpeg encoding
8935 *
8936 * PARAMETERS : none
8937 *
8938 * RETURN : exif data from user setting and GPS
8939 *==========================================================================*/
getExifData()8940 QCameraExif *QCamera2HardwareInterface::getExifData()
8941 {
8942 QCameraExif *exif = new QCameraExif();
8943 if (exif == NULL) {
8944 LOGE("No memory for QCameraExif");
8945 return NULL;
8946 }
8947
8948 int32_t rc = NO_ERROR;
8949
8950 // add exif entries
8951 String8 dateTime, subSecTime;
8952 rc = mParameters.getExifDateTime(dateTime, subSecTime);
8953 if(rc == NO_ERROR) {
8954 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
8955 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
8956 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
8957 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
8958 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
8959 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
8960 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
8961 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
8962 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
8963 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
8964 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
8965 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
8966 } else {
8967 LOGW("getExifDateTime failed");
8968 }
8969
8970 rat_t focalLength;
8971 rc = mParameters.getExifFocalLength(&focalLength);
8972 if (rc == NO_ERROR) {
8973 exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
8974 EXIF_RATIONAL,
8975 1,
8976 (void *)&(focalLength));
8977 } else {
8978 LOGW("getExifFocalLength failed");
8979 }
8980
8981 uint16_t isoSpeed = mParameters.getExifIsoSpeed();
8982 if (getSensorType() != CAM_SENSOR_YUV) {
8983 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
8984 EXIF_SHORT,
8985 1,
8986 (void *)&(isoSpeed));
8987 }
8988
8989 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
8990 uint32_t count = 0;
8991
8992 /*gps data might not be available */
8993 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
8994 if(rc == NO_ERROR) {
8995 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
8996 EXIF_ASCII,
8997 count,
8998 (void *)gpsProcessingMethod);
8999 } else {
9000 LOGW("getExifGpsProcessingMethod failed");
9001 }
9002
9003 rat_t latitude[3];
9004 char latRef[2];
9005 rc = mParameters.getExifLatitude(latitude, latRef);
9006 if(rc == NO_ERROR) {
9007 exif->addEntry(EXIFTAGID_GPS_LATITUDE,
9008 EXIF_RATIONAL,
9009 3,
9010 (void *)latitude);
9011 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
9012 EXIF_ASCII,
9013 2,
9014 (void *)latRef);
9015 } else {
9016 LOGW("getExifLatitude failed");
9017 }
9018
9019 rat_t longitude[3];
9020 char lonRef[2];
9021 rc = mParameters.getExifLongitude(longitude, lonRef);
9022 if(rc == NO_ERROR) {
9023 exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
9024 EXIF_RATIONAL,
9025 3,
9026 (void *)longitude);
9027
9028 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
9029 EXIF_ASCII,
9030 2,
9031 (void *)lonRef);
9032 } else {
9033 LOGW("getExifLongitude failed");
9034 }
9035
9036 rat_t altitude;
9037 char altRef;
9038 rc = mParameters.getExifAltitude(&altitude, &altRef);
9039 if(rc == NO_ERROR) {
9040 exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
9041 EXIF_RATIONAL,
9042 1,
9043 (void *)&(altitude));
9044
9045 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
9046 EXIF_BYTE,
9047 1,
9048 (void *)&altRef);
9049 } else {
9050 LOGW("getExifAltitude failed");
9051 }
9052
9053 char gpsDateStamp[20];
9054 rat_t gpsTimeStamp[3];
9055 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
9056 if(rc == NO_ERROR) {
9057 exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
9058 EXIF_ASCII,
9059 (uint32_t)(strlen(gpsDateStamp) + 1),
9060 (void *)gpsDateStamp);
9061
9062 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
9063 EXIF_RATIONAL,
9064 3,
9065 (void *)gpsTimeStamp);
9066 } else {
9067 LOGW("getExifGpsDataTimeStamp failed");
9068 }
9069
9070 #ifdef ENABLE_MODEL_INFO_EXIF
9071
9072 char value[PROPERTY_VALUE_MAX];
9073 if (property_get("persist.sys.exif.make", value, "") > 0 ||
9074 property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
9075 exif->addEntry(EXIFTAGID_MAKE,
9076 EXIF_ASCII, strlen(value) + 1, (void *)value);
9077 } else {
9078 LOGW("getExifMaker failed");
9079 }
9080
9081 if (property_get("persist.sys.exif.model", value, "") > 0 ||
9082 property_get("ro.product.model", value, "QCAM-AA") > 0) {
9083 exif->addEntry(EXIFTAGID_MODEL,
9084 EXIF_ASCII, strlen(value) + 1, (void *)value);
9085 } else {
9086 LOGW("getExifModel failed");
9087 }
9088
9089 if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
9090 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
9091 (uint32_t)(strlen(value) + 1), (void *)value);
9092 } else {
9093 LOGW("getExifSoftware failed");
9094 }
9095
9096 #endif
9097
9098 if (mParameters.useJpegExifRotation()) {
9099 int16_t orientation;
9100 switch (mParameters.getJpegExifRotation()) {
9101 case 0:
9102 orientation = 1;
9103 break;
9104 case 90:
9105 orientation = 6;
9106 break;
9107 case 180:
9108 orientation = 3;
9109 break;
9110 case 270:
9111 orientation = 8;
9112 break;
9113 default:
9114 orientation = 1;
9115 break;
9116 }
9117 exif->addEntry(EXIFTAGID_ORIENTATION,
9118 EXIF_SHORT,
9119 1,
9120 (void *)&orientation);
9121 exif->addEntry(EXIFTAGID_TN_ORIENTATION,
9122 EXIF_SHORT,
9123 1,
9124 (void *)&orientation);
9125 }
9126
9127 return exif;
9128 }
9129
9130 /*===========================================================================
9131 * FUNCTION : setHistogram
9132 *
9133 * DESCRIPTION: set if histogram should be enabled
9134 *
9135 * PARAMETERS :
9136 * @histogram_en : bool flag if histogram should be enabled
9137 *
9138 * RETURN : int32_t type of status
9139 * NO_ERROR -- success
9140 * none-zero failure code
9141 *==========================================================================*/
setHistogram(bool histogram_en)9142 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
9143 {
9144 return mParameters.setHistogram(histogram_en);
9145 }
9146
9147 /*===========================================================================
9148 * FUNCTION : setFaceDetection
9149 *
9150 * DESCRIPTION: set if face detection should be enabled
9151 *
9152 * PARAMETERS :
9153 * @enabled : bool flag if face detection should be enabled
9154 *
9155 * RETURN : int32_t type of status
9156 * NO_ERROR -- success
9157 * none-zero failure code
9158 *==========================================================================*/
setFaceDetection(bool enabled)9159 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
9160 {
9161 return mParameters.setFaceDetection(enabled, true);
9162 }
9163
9164 /*===========================================================================
9165 * FUNCTION : isCaptureShutterEnabled
9166 *
9167 * DESCRIPTION: Check whether shutter should be triggered immediately after
9168 * capture
9169 *
9170 * PARAMETERS :
9171 *
9172 * RETURN : true - regular capture
9173 * false - other type of capture
9174 *==========================================================================*/
isCaptureShutterEnabled()9175 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
9176 {
9177 char prop[PROPERTY_VALUE_MAX];
9178 memset(prop, 0, sizeof(prop));
9179 property_get("persist.camera.feature.shutter", prop, "0");
9180 int enableShutter = atoi(prop);
9181 return enableShutter == 1;
9182 }
9183
9184 /*===========================================================================
9185 * FUNCTION : needProcessPreviewFrame
9186 *
9187 * DESCRIPTION: returns whether preview frame need to be displayed
9188 *
9189 * PARAMETERS :
9190 * @frameID : frameID of frame to be processed
9191 *
9192 * RETURN : int32_t type of status
9193 * NO_ERROR -- success
9194 * none-zero failure code
9195 *==========================================================================*/
needProcessPreviewFrame(uint32_t frameID)9196 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
9197 {
9198 return ((m_stateMachine.isPreviewRunning()) &&
9199 (!isDisplayFrameToSkip(frameID)) &&
9200 (!mParameters.isInstantAECEnabled()));
9201 }
9202
9203 /*===========================================================================
9204 * FUNCTION : needSendPreviewCallback
9205 *
9206 * DESCRIPTION: returns whether preview frame need to callback to APP
9207 *
9208 * PARAMETERS :
9209 *
9210 * RETURN : true - need preview frame callbck
9211 * false - not send preview frame callback
9212 *==========================================================================*/
needSendPreviewCallback()9213 bool QCamera2HardwareInterface::needSendPreviewCallback()
9214 {
9215 return m_stateMachine.isPreviewRunning()
9216 && (mDataCb != NULL)
9217 && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
9218 && m_stateMachine.isPreviewCallbackNeeded();
9219 };
9220
9221 /*===========================================================================
9222 * FUNCTION : setDisplaySkip
9223 *
9224 * DESCRIPTION: set range of frames to skip for preview
9225 *
9226 * PARAMETERS :
9227 * @enabled : TRUE to start skipping frame to display
9228 FALSE to stop skipping frame to display
9229 * @skipCnt : Number of frame to skip. 0 by default
9230 *
9231 * RETURN : None
9232 *==========================================================================*/
setDisplaySkip(bool enabled,uint8_t skipCnt)9233 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
9234 {
9235 pthread_mutex_lock(&mGrallocLock);
9236 if (enabled) {
9237 setDisplayFrameSkip();
9238 setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
9239 } else {
9240 setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
9241 }
9242 pthread_mutex_unlock(&mGrallocLock);
9243 }
9244
9245 /*===========================================================================
9246 * FUNCTION : setDisplayFrameSkip
9247 *
9248 * DESCRIPTION: set range of frames to skip for preview
9249 *
9250 * PARAMETERS :
9251 * @start : frameId to start skip
9252 * @end : frameId to stop skip
9253 *
9254 * RETURN : None
9255 *==========================================================================*/
setDisplayFrameSkip(uint32_t start,uint32_t end)9256 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
9257 uint32_t end)
9258 {
9259 if (start == 0) {
9260 mFrameSkipStart = 0;
9261 mFrameSkipEnd = 0;
9262 return;
9263 }
9264 if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
9265 mFrameSkipStart = start;
9266 }
9267 if ((end == 0) || (end > mFrameSkipEnd)) {
9268 mFrameSkipEnd = end;
9269 }
9270 }
9271
9272 /*===========================================================================
9273 * FUNCTION : isDisplayFrameToSkip
9274 *
9275 * DESCRIPTION: function to determin if input frame falls under skip range
9276 *
9277 * PARAMETERS :
9278 * @frameId : frameId to verify
9279 *
9280 * RETURN : true : need to skip
9281 * false: no need to skip
9282 *==========================================================================*/
isDisplayFrameToSkip(uint32_t frameId)9283 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
9284 {
9285 return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
9286 (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
9287 }
9288
9289 /*===========================================================================
9290 * FUNCTION : prepareHardwareForSnapshot
9291 *
9292 * DESCRIPTION: prepare hardware for snapshot, such as LED
9293 *
9294 * PARAMETERS :
9295 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation
9296 *
9297 * RETURN : int32_t type of status
9298 * NO_ERROR -- success
9299 * none-zero failure code
9300 *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)9301 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
9302 {
9303 ATRACE_CALL();
9304 LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
9305 return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
9306 afNeeded);
9307 }
9308
9309 /*===========================================================================
9310 * FUNCTION : needFDMetadata
9311 *
9312 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
9313 *
9314 * PARAMETERS :
9315 * @channel_type: channel type
9316 *
9317 * RETURN : true: needed
9318 * false: no need
9319 *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)9320 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
9321 {
9322 //Note: Currently we only process ZSL channel
9323 bool value = false;
9324 if(channel_type == QCAMERA_CH_TYPE_ZSL){
9325 //check if FD requirement is enabled
9326 if(mParameters.isSnapshotFDNeeded() &&
9327 mParameters.isFaceDetectionEnabled()){
9328 value = true;
9329 LOGH("Face Detection metadata is required in ZSL mode.");
9330 }
9331 }
9332
9333 return value;
9334 }
9335
9336 /*===========================================================================
9337 * FUNCTION : deferredWorkRoutine
9338 *
9339 * DESCRIPTION: data process routine that executes deferred tasks
9340 *
9341 * PARAMETERS :
9342 * @data : user data ptr (QCamera2HardwareInterface)
9343 *
9344 * RETURN : None
9345 *==========================================================================*/
deferredWorkRoutine(void * obj)9346 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
9347 {
9348 int running = 1;
9349 int ret;
9350 uint8_t is_active = FALSE;
9351 int32_t job_status = 0;
9352
9353 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
9354 QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
9355 cmdThread->setName("CAM_defrdWrk");
9356
9357 do {
9358 do {
9359 ret = cam_sem_wait(&cmdThread->cmd_sem);
9360 if (ret != 0 && errno != EINVAL) {
9361 LOGE("cam_sem_wait error (%s)",
9362 strerror(errno));
9363 return NULL;
9364 }
9365 } while (ret != 0);
9366
9367 // we got notified about new cmd avail in cmd queue
9368 camera_cmd_type_t cmd = cmdThread->getCmd();
9369 LOGD("cmd: %d", cmd);
9370 switch (cmd) {
9371 case CAMERA_CMD_TYPE_START_DATA_PROC:
9372 LOGH("start data proc");
9373 is_active = TRUE;
9374 break;
9375 case CAMERA_CMD_TYPE_STOP_DATA_PROC:
9376 LOGH("stop data proc");
9377 is_active = FALSE;
9378 // signal cmd is completed
9379 cam_sem_post(&cmdThread->sync_sem);
9380 break;
9381 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
9382 {
9383 DefWork *dw =
9384 reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
9385
9386 if ( NULL == dw ) {
9387 LOGE("Invalid deferred work");
9388 break;
9389 }
9390
9391 switch( dw->cmd ) {
9392 case CMD_DEF_ALLOCATE_BUFF:
9393 {
9394 QCameraChannel * pChannel = dw->args.allocArgs.ch;
9395
9396 if ( NULL == pChannel ) {
9397 LOGE("Invalid deferred work channel");
9398 job_status = BAD_VALUE;
9399 break;
9400 }
9401
9402 cam_stream_type_t streamType = dw->args.allocArgs.type;
9403 LOGH("Deferred buffer allocation started for stream type: %d",
9404 streamType);
9405
9406 uint32_t iNumOfStreams = pChannel->getNumOfStreams();
9407 QCameraStream *pStream = NULL;
9408 for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
9409 pStream = pChannel->getStreamByIndex(i);
9410
9411 if ( NULL == pStream ) {
9412 job_status = BAD_VALUE;
9413 break;
9414 }
9415
9416 if ( pStream->isTypeOf(streamType)) {
9417 if ( pStream->allocateBuffers() ) {
9418 LOGE("Error allocating buffers !!!");
9419 job_status = NO_MEMORY;
9420 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9421 CAMERA_ERROR_UNKNOWN, 0);
9422 }
9423 break;
9424 }
9425 }
9426 }
9427 break;
9428 case CMD_DEF_PPROC_START:
9429 {
9430 int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
9431 if (ret != NO_ERROR) {
9432 job_status = ret;
9433 LOGE("PPROC Start failed");
9434 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9435 CAMERA_ERROR_UNKNOWN, 0);
9436 break;
9437 }
9438 QCameraChannel * pChannel = dw->args.pprocArgs;
9439 assert(pChannel);
9440
9441 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
9442 LOGE("cannot start postprocessor");
9443 job_status = BAD_VALUE;
9444 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9445 CAMERA_ERROR_UNKNOWN, 0);
9446 }
9447 }
9448 break;
9449 case CMD_DEF_METADATA_ALLOC:
9450 {
9451 int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
9452 if (ret != NO_ERROR) {
9453 job_status = ret;
9454 LOGE("Metadata alloc failed");
9455 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9456 CAMERA_ERROR_UNKNOWN, 0);
9457 break;
9458 }
9459 pme->mMetadataMem = new QCameraMetadataStreamMemory(
9460 QCAMERA_ION_USE_CACHE);
9461
9462 if (pme->mMetadataMem == NULL) {
9463 LOGE("Unable to allocate metadata buffers");
9464 job_status = BAD_VALUE;
9465 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9466 CAMERA_ERROR_UNKNOWN, 0);
9467 } else {
9468 int32_t rc = pme->mMetadataMem->allocate(
9469 dw->args.metadataAllocArgs.bufferCnt,
9470 dw->args.metadataAllocArgs.size,
9471 NON_SECURE);
9472 if (rc < 0) {
9473 delete pme->mMetadataMem;
9474 pme->mMetadataMem = NULL;
9475 }
9476 }
9477 }
9478 break;
9479 case CMD_DEF_CREATE_JPEG_SESSION:
9480 {
9481 QCameraChannel * pChannel = dw->args.pprocArgs;
9482 assert(pChannel);
9483
9484 int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
9485 if (ret != NO_ERROR) {
9486 job_status = ret;
9487 LOGE("Jpeg create failed");
9488 break;
9489 }
9490
9491 if (pme->m_postprocessor.createJpegSession(pChannel)
9492 != NO_ERROR) {
9493 LOGE("cannot create JPEG session");
9494 job_status = UNKNOWN_ERROR;
9495 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9496 CAMERA_ERROR_UNKNOWN, 0);
9497 }
9498 }
9499 break;
9500 case CMD_DEF_PPROC_INIT:
9501 {
9502 int32_t rc = NO_ERROR;
9503
9504 jpeg_encode_callback_t jpegEvtHandle =
9505 dw->args.pprocInitArgs.jpeg_cb;
9506 void* user_data = dw->args.pprocInitArgs.user_data;
9507 QCameraPostProcessor *postProcessor =
9508 &(pme->m_postprocessor);
9509 uint32_t cameraId = pme->mCameraId;
9510 cam_capability_t *capability =
9511 gCamCapability[cameraId];
9512 cam_padding_info_t padding_info;
9513 cam_padding_info_t& cam_capability_padding_info =
9514 capability->padding_info;
9515
9516 if(!pme->mJpegClientHandle) {
9517 rc = pme->initJpegHandle();
9518 if (rc != NO_ERROR) {
9519 LOGE("Error!! creating JPEG handle failed");
9520 job_status = UNKNOWN_ERROR;
9521 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9522 CAMERA_ERROR_UNKNOWN, 0);
9523 break;
9524 }
9525 }
9526 LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
9527
9528 rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
9529 &pme->mJpegMpoHandle,
9530 pme->mJpegClientHandle);
9531 if (rc != 0) {
9532 LOGE("Error!! set JPEG handle failed");
9533 job_status = UNKNOWN_ERROR;
9534 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9535 CAMERA_ERROR_UNKNOWN, 0);
9536 break;
9537 }
9538
9539 /* get max pic size for jpeg work buf calculation*/
9540 rc = postProcessor->init(jpegEvtHandle, user_data);
9541
9542 if (rc != NO_ERROR) {
9543 LOGE("cannot init postprocessor");
9544 job_status = UNKNOWN_ERROR;
9545 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9546 CAMERA_ERROR_UNKNOWN, 0);
9547 break;
9548 }
9549
9550 // update padding info from jpeg
9551 postProcessor->getJpegPaddingReq(padding_info);
9552 if (cam_capability_padding_info.width_padding <
9553 padding_info.width_padding) {
9554 cam_capability_padding_info.width_padding =
9555 padding_info.width_padding;
9556 }
9557 if (cam_capability_padding_info.height_padding <
9558 padding_info.height_padding) {
9559 cam_capability_padding_info.height_padding =
9560 padding_info.height_padding;
9561 }
9562 if (cam_capability_padding_info.plane_padding !=
9563 padding_info.plane_padding) {
9564 cam_capability_padding_info.plane_padding =
9565 mm_stream_calc_lcm(
9566 cam_capability_padding_info.plane_padding,
9567 padding_info.plane_padding);
9568 }
9569 if (cam_capability_padding_info.offset_info.offset_x
9570 != padding_info.offset_info.offset_x) {
9571 cam_capability_padding_info.offset_info.offset_x =
9572 mm_stream_calc_lcm (
9573 cam_capability_padding_info.offset_info.offset_x,
9574 padding_info.offset_info.offset_x);
9575 }
9576 if (cam_capability_padding_info.offset_info.offset_y
9577 != padding_info.offset_info.offset_y) {
9578 cam_capability_padding_info.offset_info.offset_y =
9579 mm_stream_calc_lcm (
9580 cam_capability_padding_info.offset_info.offset_y,
9581 padding_info.offset_info.offset_y);
9582 }
9583 }
9584 break;
9585 case CMD_DEF_PARAM_ALLOC:
9586 {
9587 int32_t rc = pme->mParameters.allocate();
9588 // notify routine would not be initialized by this time.
9589 // So, just update error job status
9590 if (rc != NO_ERROR) {
9591 job_status = rc;
9592 LOGE("Param allocation failed");
9593 break;
9594 }
9595 }
9596 break;
9597 case CMD_DEF_PARAM_INIT:
9598 {
9599 int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
9600 if (rc != NO_ERROR) {
9601 job_status = rc;
9602 LOGE("Param init failed");
9603 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9604 CAMERA_ERROR_UNKNOWN, 0);
9605 break;
9606 }
9607
9608 uint32_t camId = pme->mCameraId;
9609 cam_capability_t * cap = gCamCapability[camId];
9610
9611 if (pme->mCameraHandle == NULL) {
9612 LOGE("Camera handle is null");
9613 job_status = BAD_VALUE;
9614 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9615 CAMERA_ERROR_UNKNOWN, 0);
9616 break;
9617 }
9618
9619 // Now PostProc need calibration data as initialization
9620 // time for jpeg_open and calibration data is a
9621 // get param for now, so params needs to be initialized
9622 // before postproc init
9623 rc = pme->mParameters.init(cap,
9624 pme->mCameraHandle,
9625 pme);
9626 if (rc != 0) {
9627 job_status = UNKNOWN_ERROR;
9628 LOGE("Parameter Initialization failed");
9629 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9630 CAMERA_ERROR_UNKNOWN, 0);
9631 break;
9632 }
9633
9634 // Get related cam calibration only in
9635 // dual camera mode
9636 if (pme->getRelatedCamSyncInfo()->sync_control ==
9637 CAM_SYNC_RELATED_SENSORS_ON) {
9638 rc = pme->mParameters.getRelatedCamCalibration(
9639 &(pme->mJpegMetadata.otp_calibration_data));
9640 LOGD("Dumping Calibration Data Version Id %f rc %d",
9641 pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
9642 rc);
9643 if (rc != 0) {
9644 job_status = UNKNOWN_ERROR;
9645 LOGE("getRelatedCamCalibration failed");
9646 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9647 CAMERA_ERROR_UNKNOWN, 0);
9648 break;
9649 }
9650 pme->m_bRelCamCalibValid = true;
9651 }
9652
9653 pme->mJpegMetadata.sensor_mount_angle =
9654 cap->sensor_mount_angle;
9655 pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
9656
9657 pme->mParameters.setMinPpMask(
9658 cap->qcom_supported_feature_mask);
9659 pme->mExifParams.debug_params =
9660 (mm_jpeg_debug_exif_params_t *)
9661 malloc(sizeof(mm_jpeg_debug_exif_params_t));
9662 if (!pme->mExifParams.debug_params) {
9663 LOGE("Out of Memory. Allocation failed for "
9664 "3A debug exif params");
9665 job_status = NO_MEMORY;
9666 pme->sendEvtNotify(CAMERA_MSG_ERROR,
9667 CAMERA_ERROR_UNKNOWN, 0);
9668 break;
9669 }
9670 memset(pme->mExifParams.debug_params, 0,
9671 sizeof(mm_jpeg_debug_exif_params_t));
9672 }
9673 break;
9674 case CMD_DEF_GENERIC:
9675 {
9676 BackgroundTask *bgTask = dw->args.genericArgs;
9677 job_status = bgTask->bgFunction(bgTask->bgArgs);
9678 }
9679 break;
9680 default:
9681 LOGE("Incorrect command : %d", dw->cmd);
9682 }
9683
9684 pme->dequeueDeferredWork(dw, job_status);
9685 }
9686 break;
9687 case CAMERA_CMD_TYPE_EXIT:
9688 running = 0;
9689 break;
9690 default:
9691 break;
9692 }
9693 } while (running);
9694
9695 return NULL;
9696 }
9697
9698 /*===========================================================================
9699 * FUNCTION : queueDeferredWork
9700 *
9701 * DESCRIPTION: function which queues deferred tasks
9702 *
9703 * PARAMETERS :
9704 * @cmd : deferred task
9705 * @args : deferred task arguments
9706 *
9707 * RETURN : job id of deferred job
9708 * : 0 in case of error
9709 *==========================================================================*/
queueDeferredWork(DeferredWorkCmd cmd,DeferWorkArgs args)9710 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
9711 DeferWorkArgs args)
9712 {
9713 Mutex::Autolock l(mDefLock);
9714 for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
9715 if (mDefOngoingJobs[i].mDefJobId == 0) {
9716 DefWork *dw = new DefWork(cmd, sNextJobId, args);
9717 if (!dw) {
9718 LOGE("out of memory.");
9719 return 0;
9720 }
9721 if (mCmdQueue.enqueue(dw)) {
9722 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
9723 mDefOngoingJobs[i].mDefJobStatus = 0;
9724 if (sNextJobId == 0) { // handle overflow
9725 sNextJobId = 1;
9726 }
9727 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
9728 FALSE,
9729 FALSE);
9730 return mDefOngoingJobs[i].mDefJobId;
9731 } else {
9732 LOGD("Command queue not active! cmd = %d", cmd);
9733 delete dw;
9734 return 0;
9735 }
9736 }
9737 }
9738 return 0;
9739 }
9740
9741 /*===========================================================================
9742 * FUNCTION : initJpegHandle
9743 *
9744 * DESCRIPTION: Opens JPEG client and gets a handle.
9745 * Sends Dual cam calibration info if present
9746 *
9747 * RETURN : int32_t type of status
9748 * NO_ERROR -- success
9749 * none-zero failure code
9750 *==========================================================================*/
initJpegHandle()9751 int32_t QCamera2HardwareInterface::initJpegHandle() {
9752 // Check if JPEG client handle is present
9753 LOGH("E");
9754 if(!mJpegClientHandle) {
9755 mm_dimension max_size = {0, 0};
9756 cam_dimension_t size;
9757
9758 mParameters.getMaxPicSize(size);
9759 max_size.w = size.width;
9760 max_size.h = size.height;
9761
9762 if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
9763 if (m_bRelCamCalibValid) {
9764 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
9765 max_size, &mJpegMetadata);
9766 } else {
9767 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
9768 max_size, NULL);
9769 }
9770 } else {
9771 mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
9772 }
9773 if (!mJpegClientHandle) {
9774 LOGE("Error !! jpeg_open failed!! ");
9775 return UNKNOWN_ERROR;
9776 }
9777 // Set JPEG initialized as true to signify that this camera
9778 // has initialized the handle
9779 mJpegHandleOwner = true;
9780 }
9781 LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
9782 mJpegHandleOwner, mJpegClientHandle, mCameraId);
9783 return NO_ERROR;
9784 }
9785
9786 /*===========================================================================
9787 * FUNCTION : deinitJpegHandle
9788 *
9789 * DESCRIPTION: Closes JPEG client using handle
9790 *
9791 * RETURN : int32_t type of status
9792 * NO_ERROR -- success
9793 * none-zero failure code
9794 *==========================================================================*/
deinitJpegHandle()9795 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
9796 int32_t rc = NO_ERROR;
9797 LOGH("E");
9798 // Check if JPEG client handle is present and inited by this camera
9799 if(mJpegHandleOwner && mJpegClientHandle) {
9800 rc = mJpegHandle.close(mJpegClientHandle);
9801 if (rc != NO_ERROR) {
9802 LOGE("Error!! Closing mJpegClientHandle: %d failed",
9803 mJpegClientHandle);
9804 }
9805 memset(&mJpegHandle, 0, sizeof(mJpegHandle));
9806 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
9807 mJpegHandleOwner = false;
9808 }
9809 mJpegClientHandle = 0;
9810 LOGH("X rc = %d", rc);
9811 return rc;
9812 }
9813
9814 /*===========================================================================
9815 * FUNCTION : setJpegHandleInfo
9816 *
9817 * DESCRIPTION: sets JPEG client handle info
9818 *
9819 * PARAMETERS:
9820 * @ops : JPEG ops
9821 * @mpo_ops : Jpeg MPO ops
9822 * @pJpegClientHandle : o/p Jpeg Client Handle
9823 *
9824 * RETURN : int32_t type of status
9825 * NO_ERROR -- success
9826 * none-zero failure code
9827 *==========================================================================*/
setJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t pJpegClientHandle)9828 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
9829 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
9830
9831 if (pJpegClientHandle && ops && mpo_ops) {
9832 LOGH("Setting JPEG client handle %d",
9833 pJpegClientHandle);
9834 memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
9835 memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
9836 mJpegClientHandle = pJpegClientHandle;
9837 return NO_ERROR;
9838 }
9839 else {
9840 LOGE("Error!! No Handle found: %d",
9841 pJpegClientHandle);
9842 return BAD_VALUE;
9843 }
9844 }
9845
9846 /*===========================================================================
9847 * FUNCTION : getJpegHandleInfo
9848 *
9849 * DESCRIPTION: gets JPEG client handle info
9850 *
9851 * PARAMETERS:
9852 * @ops : JPEG ops
9853 * @mpo_ops : Jpeg MPO ops
9854 * @pJpegClientHandle : o/p Jpeg Client Handle
9855 *
9856 * RETURN : int32_t type of status
9857 * NO_ERROR -- success
9858 * none-zero failure code
9859 *==========================================================================*/
getJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t * pJpegClientHandle)9860 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
9861 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
9862
9863 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
9864 LOGE("Init PProc Deferred work failed");
9865 return UNKNOWN_ERROR;
9866 }
9867 // Copy JPEG ops if present
9868 if (ops && mpo_ops && pJpegClientHandle) {
9869 memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
9870 memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
9871 *pJpegClientHandle = mJpegClientHandle;
9872 LOGH("Getting JPEG client handle %d",
9873 pJpegClientHandle);
9874 return NO_ERROR;
9875 } else {
9876 return BAD_VALUE;
9877 }
9878 }
9879
9880 /*===========================================================================
9881 * FUNCTION : dequeueDeferredWork
9882 *
9883 * DESCRIPTION: function which dequeues deferred tasks
9884 *
9885 * PARAMETERS :
9886 * @dw : deferred work
9887 * @jobStatus: deferred task job status
9888 *
9889 * RETURN : int32_t type of status
9890 * NO_ERROR -- success
9891 * none-zero failure code
9892 *==========================================================================*/
dequeueDeferredWork(DefWork * dw,int32_t jobStatus)9893 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
9894 {
9895 Mutex::Autolock l(mDefLock);
9896 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
9897 if (mDefOngoingJobs[i].mDefJobId == dw->id) {
9898 if (jobStatus != NO_ERROR) {
9899 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
9900 LOGH("updating job status %d for id %d",
9901 jobStatus, dw->id);
9902 } else {
9903 mDefOngoingJobs[i].mDefJobId = 0;
9904 mDefOngoingJobs[i].mDefJobStatus = 0;
9905 }
9906 delete dw;
9907 mDefCond.broadcast();
9908 return NO_ERROR;
9909 }
9910 }
9911
9912 return UNKNOWN_ERROR;
9913 }
9914
9915 /*===========================================================================
9916 * FUNCTION : getDefJobStatus
9917 *
9918 * DESCRIPTION: Gets if a deferred task is success/fail
9919 *
9920 * PARAMETERS :
9921 * @job_id : deferred task id
9922 *
9923 * RETURN : NO_ERROR if the job success, otherwise false
9924 *
9925 * PRECONDITION : mDefLock is held by current thread
9926 *==========================================================================*/
getDefJobStatus(uint32_t & job_id)9927 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
9928 {
9929 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
9930 if (mDefOngoingJobs[i].mDefJobId == job_id) {
9931 if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
9932 LOGE("job_id (%d) was failed", job_id);
9933 return mDefOngoingJobs[i].mDefJobStatus;
9934 }
9935 else
9936 return NO_ERROR;
9937 }
9938 }
9939 return NO_ERROR;
9940 }
9941
9942
9943 /*===========================================================================
9944 * FUNCTION : checkDeferredWork
9945 *
9946 * DESCRIPTION: checks if a deferred task is in progress
9947 *
9948 * PARAMETERS :
9949 * @job_id : deferred task id
9950 *
9951 * RETURN : true if the task exists, otherwise false
9952 *
9953 * PRECONDITION : mDefLock is held by current thread
9954 *==========================================================================*/
checkDeferredWork(uint32_t & job_id)9955 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
9956 {
9957 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
9958 if (mDefOngoingJobs[i].mDefJobId == job_id) {
9959 return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
9960 }
9961 }
9962 return false;
9963 }
9964
9965 /*===========================================================================
9966 * FUNCTION : waitDeferredWork
9967 *
9968 * DESCRIPTION: waits for a deferred task to finish
9969 *
9970 * PARAMETERS :
9971 * @job_id : deferred task id
9972 *
9973 * RETURN : int32_t type of status
9974 * NO_ERROR -- success
9975 * none-zero failure code
9976 *==========================================================================*/
waitDeferredWork(uint32_t & job_id)9977 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
9978 {
9979 Mutex::Autolock l(mDefLock);
9980
9981 if (job_id == 0) {
9982 LOGD("Invalid job id %d", job_id);
9983 return NO_ERROR;
9984 }
9985
9986 while (checkDeferredWork(job_id) == true ) {
9987 mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
9988 }
9989 return getDefJobStatus(job_id);
9990 }
9991
9992 /*===========================================================================
9993 * FUNCTION : scheduleBackgroundTask
9994 *
9995 * DESCRIPTION: Run a requested task in the deferred thread
9996 *
9997 * PARAMETERS :
9998 * @bgTask : Task to perform in the background
9999 *
10000 * RETURN : job id of deferred job
10001 * : 0 in case of error
10002 *==========================================================================*/
scheduleBackgroundTask(BackgroundTask * bgTask)10003 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
10004 {
10005 DeferWorkArgs args;
10006 memset(&args, 0, sizeof(DeferWorkArgs));
10007 args.genericArgs = bgTask;
10008
10009 return queueDeferredWork(CMD_DEF_GENERIC, args);
10010 }
10011
10012 /*===========================================================================
10013 * FUNCTION : waitForBackgroundTask
10014 *
10015 * DESCRIPTION: Wait for a background task to complete
10016 *
10017 * PARAMETERS :
10018 * @taskId : Task id to wait for
10019 *
10020 * RETURN : int32_t type of status
10021 * NO_ERROR -- success
10022 * none-zero failure code
10023 *==========================================================================*/
waitForBackgroundTask(uint32_t & taskId)10024 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
10025 {
10026 return waitDeferredWork(taskId);
10027 }
10028
10029 /*===========================================================================
10030 * FUNCTION : needDeferedAllocation
10031 *
10032 * DESCRIPTION: Function to decide background task for streams
10033 *
10034 * PARAMETERS :
10035 * @stream_type : stream type
10036 *
10037 * RETURN : true - if background task is needed
10038 * false - if background task is NOT needed
10039 *==========================================================================*/
needDeferred(cam_stream_type_t stream_type)10040 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
10041 {
10042 if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
10043 || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
10044 return FALSE;
10045 }
10046
10047 if ((stream_type == CAM_STREAM_TYPE_RAW)
10048 && (mParameters.getofflineRAW())) {
10049 return FALSE;
10050 }
10051
10052 if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
10053 && (!mParameters.getRecordingHintValue())){
10054 return TRUE;
10055 }
10056
10057 if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
10058 || (stream_type == CAM_STREAM_TYPE_METADATA)
10059 || (stream_type == CAM_STREAM_TYPE_RAW)
10060 || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
10061 return TRUE;
10062 }
10063
10064 if (stream_type == CAM_STREAM_TYPE_VIDEO) {
10065 return FALSE;
10066 }
10067 return FALSE;
10068 }
10069
10070 /*===========================================================================
10071 * FUNCTION : isRegularCapture
10072 *
10073 * DESCRIPTION: Check configuration for regular catpure
10074 *
10075 * PARAMETERS :
10076 *
10077 * RETURN : true - regular capture
10078 * false - other type of capture
10079 *==========================================================================*/
isRegularCapture()10080 bool QCamera2HardwareInterface::isRegularCapture()
10081 {
10082 bool ret = false;
10083
10084 if (numOfSnapshotsExpected() == 1 &&
10085 !isLongshotEnabled() &&
10086 !mParameters.isHDREnabled() &&
10087 !mParameters.getRecordingHintValue() &&
10088 !isZSLMode() && !mParameters.getofflineRAW()) {
10089 ret = true;
10090 }
10091 return ret;
10092 }
10093
10094 /*===========================================================================
10095 * FUNCTION : getLogLevel
10096 *
10097 * DESCRIPTION: Reads the log level property into a variable
10098 *
10099 * PARAMETERS :
10100 * None
10101 *
10102 * RETURN :
10103 * None
10104 *==========================================================================*/
getLogLevel()10105 void QCamera2HardwareInterface::getLogLevel()
10106 {
10107 char prop[PROPERTY_VALUE_MAX];
10108
10109 property_get("persist.camera.kpi.debug", prop, "1");
10110 gKpiDebugLevel = atoi(prop);
10111 return;
10112 }
10113
10114 /*===========================================================================
10115 * FUNCTION : getSensorType
10116 *
10117 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
10118 *
10119 * PARAMETERS :
10120 * None
10121 *
10122 * RETURN : Type of sensor - bayer or YUV
10123 *
10124 *==========================================================================*/
getSensorType()10125 cam_sensor_t QCamera2HardwareInterface::getSensorType()
10126 {
10127 return gCamCapability[mCameraId]->sensor_type.sens_type;
10128 }
10129
10130 /*===========================================================================
10131 * FUNCTION : startRAWChannel
10132 *
10133 * DESCRIPTION: start RAW Channel
10134 *
10135 * PARAMETERS :
10136 * @pChannel : Src channel to link this RAW channel.
10137 *
10138 * RETURN : int32_t type of status
10139 * NO_ERROR -- success
10140 * none-zero failure code
10141 *==========================================================================*/
startRAWChannel(QCameraChannel * pMetaChannel)10142 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
10143 {
10144 int32_t rc = NO_ERROR;
10145 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
10146 if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
10147 // Find and try to link a metadata stream from preview channel
10148 QCameraStream *pMetaStream = NULL;
10149
10150 if (pMetaChannel != NULL) {
10151 uint32_t streamNum = pMetaChannel->getNumOfStreams();
10152 QCameraStream *pStream = NULL;
10153 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
10154 pStream = pMetaChannel->getStreamByIndex(i);
10155 if ((NULL != pStream) &&
10156 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
10157 pMetaStream = pStream;
10158 break;
10159 }
10160 }
10161
10162 if (NULL != pMetaStream) {
10163 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
10164 if (NO_ERROR != rc) {
10165 LOGE("Metadata stream link failed %d", rc);
10166 }
10167 }
10168 }
10169 rc = pChannel->start();
10170 }
10171 return rc;
10172 }
10173
10174 /*===========================================================================
10175 * FUNCTION : startRecording
10176 *
10177 * DESCRIPTION: start recording impl
10178 *
10179 * PARAMETERS : none
10180 *
10181 * RETURN : int32_t type of status
10182 * NO_ERROR -- success
10183 * none-zero failure code
10184 *==========================================================================*/
stopRAWChannel()10185 int32_t QCamera2HardwareInterface::stopRAWChannel()
10186 {
10187 int32_t rc = NO_ERROR;
10188 rc = stopChannel(QCAMERA_CH_TYPE_RAW);
10189 return rc;
10190 }
10191
10192 /*===========================================================================
10193 * FUNCTION : isLowPowerMode
10194 *
10195 * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
10196 *
10197 * PARAMETERS :
10198 * None
10199 *
10200 * RETURN : TRUE/FALSE
10201 *
10202 *==========================================================================*/
isLowPowerMode()10203 bool QCamera2HardwareInterface::isLowPowerMode()
10204 {
10205 cam_dimension_t dim;
10206 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
10207
10208 char prop[PROPERTY_VALUE_MAX];
10209 property_get("camera.lowpower.record.enable", prop, "0");
10210 int enable = atoi(prop);
10211
10212 //Enable low power mode if :
10213 //1. Video resolution is 2k (2048x1080) or above and
10214 //2. camera.lowpower.record.enable is set
10215
10216 bool isLowpower = mParameters.getRecordingHintValue() && enable
10217 && ((dim.width * dim.height) >= (2048 * 1080));
10218 return isLowpower;
10219 }
10220
10221 }; // namespace qcamera
10222