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