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