1 /* Copyright (c) 2012-2015, The Linux Foundataion. 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 #define ATRACE_TAG ATRACE_TAG_CAMERA
32
33 #include <utils/Log.h>
34 #include <cutils/properties.h>
35 #include <hardware/camera.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <utils/Errors.h>
39 #include <utils/Trace.h>
40 #include <gralloc_priv.h>
41 #include <gui/Surface.h>
42
43 #include "QCamera2HWI.h"
44 #include "QCameraMem.h"
45
46 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \
47 ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset)
48 #define CAMERA_MIN_STREAMING_BUFFERS 3
49 #define EXTRA_ZSL_PREVIEW_STREAM_BUF 2
50 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
51 #define CAMERA_MIN_VIDEO_BUFFERS 9
52 #define CAMERA_LONGSHOT_STAGES 4
53 #define CAMERA_MIN_VIDEO_BATCH_BUFFERS 6
54
55 //This multiplier signifies extra buffers that we need to allocate
56 //for the output of pproc
57 #define CAMERA_PPROC_OUT_BUFFER_MULTIPLIER 2
58
59
60 #define HDR_CONFIDENCE_THRESHOLD 0.4
61
62 namespace qcamera {
63
64 cam_capability_t *gCamCaps[MM_CAMERA_MAX_NUM_SENSORS];
65 static pthread_mutex_t g_camlock = PTHREAD_MUTEX_INITIALIZER;
66 volatile uint32_t gCamHalLogLevel = 1;
67
68 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
69 set_preview_window: QCamera2HardwareInterface::set_preview_window,
70 set_callbacks: QCamera2HardwareInterface::set_CallBacks,
71 enable_msg_type: QCamera2HardwareInterface::enable_msg_type,
72 disable_msg_type: QCamera2HardwareInterface::disable_msg_type,
73 msg_type_enabled: QCamera2HardwareInterface::msg_type_enabled,
74
75 start_preview: QCamera2HardwareInterface::start_preview,
76 stop_preview: QCamera2HardwareInterface::stop_preview,
77 preview_enabled: QCamera2HardwareInterface::preview_enabled,
78 store_meta_data_in_buffers: QCamera2HardwareInterface::store_meta_data_in_buffers,
79
80 start_recording: QCamera2HardwareInterface::start_recording,
81 stop_recording: QCamera2HardwareInterface::stop_recording,
82 recording_enabled: QCamera2HardwareInterface::recording_enabled,
83 release_recording_frame: QCamera2HardwareInterface::release_recording_frame,
84
85 auto_focus: QCamera2HardwareInterface::auto_focus,
86 cancel_auto_focus: QCamera2HardwareInterface::cancel_auto_focus,
87
88 take_picture: QCamera2HardwareInterface::take_picture,
89 cancel_picture: QCamera2HardwareInterface::cancel_picture,
90
91 set_parameters: QCamera2HardwareInterface::set_parameters,
92 get_parameters: QCamera2HardwareInterface::get_parameters,
93 put_parameters: QCamera2HardwareInterface::put_parameters,
94 send_command: QCamera2HardwareInterface::send_command,
95
96 release: QCamera2HardwareInterface::release,
97 dump: QCamera2HardwareInterface::dump,
98 };
99
100 /*===========================================================================
101 * FUNCTION : set_preview_window
102 *
103 * DESCRIPTION: set preview window.
104 *
105 * PARAMETERS :
106 * @device : ptr to camera device struct
107 * @window : window ops table
108 *
109 * RETURN : int32_t type of status
110 * NO_ERROR -- success
111 * none-zero failure code
112 *==========================================================================*/
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)113 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
114 struct preview_stream_ops *window)
115 {
116 ATRACE_CALL();
117 int rc = NO_ERROR;
118 QCamera2HardwareInterface *hw =
119 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
120 if (!hw) {
121 ALOGE("%s: NULL camera device", __func__);
122 return BAD_VALUE;
123 }
124
125 hw->lockAPI();
126 qcamera_api_result_t apiResult;
127 rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
128 if (rc == NO_ERROR) {
129 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
130 rc = apiResult.status;
131 }
132 hw->unlockAPI();
133
134 return rc;
135 }
136
137 /*===========================================================================
138 * FUNCTION : set_CallBacks
139 *
140 * DESCRIPTION: set callbacks for notify and data
141 *
142 * PARAMETERS :
143 * @device : ptr to camera device struct
144 * @notify_cb : notify cb
145 * @data_cb : data cb
146 * @data_cb_timestamp : video data cd with timestamp
147 * @get_memory : ops table for request gralloc memory
148 * @user : user data ptr
149 *
150 * RETURN : none
151 *==========================================================================*/
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)152 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
153 camera_notify_callback notify_cb,
154 camera_data_callback data_cb,
155 camera_data_timestamp_callback data_cb_timestamp,
156 camera_request_memory get_memory,
157 void *user)
158 {
159 ATRACE_CALL();
160 QCamera2HardwareInterface *hw =
161 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
162 if (!hw) {
163 ALOGE("NULL camera device");
164 return;
165 }
166
167 qcamera_sm_evt_setcb_payload_t payload;
168 payload.notify_cb = notify_cb;
169 payload.data_cb = data_cb;
170 payload.data_cb_timestamp = data_cb_timestamp;
171 payload.get_memory = get_memory;
172 payload.user = user;
173
174 hw->lockAPI();
175 qcamera_api_result_t apiResult;
176 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
177 if (rc == NO_ERROR) {
178 hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
179 }
180 hw->unlockAPI();
181 }
182
183 /*===========================================================================
184 * FUNCTION : enable_msg_type
185 *
186 * DESCRIPTION: enable certain msg type
187 *
188 * PARAMETERS :
189 * @device : ptr to camera device struct
190 * @msg_type : msg type mask
191 *
192 * RETURN : none
193 *==========================================================================*/
enable_msg_type(struct camera_device * device,int32_t msg_type)194 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
195 {
196 ATRACE_CALL();
197 QCamera2HardwareInterface *hw =
198 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
199 if (!hw) {
200 ALOGE("NULL camera device");
201 return;
202 }
203 hw->lockAPI();
204 qcamera_api_result_t apiResult;
205 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
206 if (rc == NO_ERROR) {
207 hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
208 }
209 hw->unlockAPI();
210 }
211
212 /*===========================================================================
213 * FUNCTION : disable_msg_type
214 *
215 * DESCRIPTION: disable certain msg type
216 *
217 * PARAMETERS :
218 * @device : ptr to camera device struct
219 * @msg_type : msg type mask
220 *
221 * RETURN : none
222 *==========================================================================*/
disable_msg_type(struct camera_device * device,int32_t msg_type)223 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
224 {
225 ATRACE_CALL();
226 QCamera2HardwareInterface *hw =
227 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
228 if (!hw) {
229 ALOGE("NULL camera device");
230 return;
231 }
232 hw->lockAPI();
233 qcamera_api_result_t apiResult;
234 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
235 if (rc == NO_ERROR) {
236 hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
237 }
238 hw->unlockAPI();
239 }
240
241 /*===========================================================================
242 * FUNCTION : msg_type_enabled
243 *
244 * DESCRIPTION: if certain msg type is enabled
245 *
246 * PARAMETERS :
247 * @device : ptr to camera device struct
248 * @msg_type : msg type mask
249 *
250 * RETURN : 1 -- enabled
251 * 0 -- not enabled
252 *==========================================================================*/
msg_type_enabled(struct camera_device * device,int32_t msg_type)253 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
254 {
255 ATRACE_CALL();
256 int ret = NO_ERROR;
257 QCamera2HardwareInterface *hw =
258 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
259 if (!hw) {
260 ALOGE("NULL camera device");
261 return BAD_VALUE;
262 }
263 hw->lockAPI();
264 qcamera_api_result_t apiResult;
265 ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
266 if (ret == NO_ERROR) {
267 hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
268 ret = apiResult.enabled;
269 }
270 hw->unlockAPI();
271
272 return ret;
273 }
274
275 /*===========================================================================
276 * FUNCTION : start_preview
277 *
278 * DESCRIPTION: start preview
279 *
280 * PARAMETERS :
281 * @device : ptr to camera device struct
282 *
283 * RETURN : int32_t type of status
284 * NO_ERROR -- success
285 * none-zero failure code
286 *==========================================================================*/
start_preview(struct camera_device * device)287 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
288 {
289 ATRACE_CALL();
290 int ret = NO_ERROR;
291 QCamera2HardwareInterface *hw =
292 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
293 if (!hw) {
294 ALOGE("NULL camera device");
295 return BAD_VALUE;
296 }
297 ALOGI("[KPI Perf] %s: E PROFILE_START_PREVIEW", __func__);
298 hw->m_perfLock.lock_acq();
299 hw->lockAPI();
300 qcamera_api_result_t apiResult;
301 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
302 if (hw->isNoDisplayMode()) {
303 evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
304 }
305 ret = hw->processAPI(evt, NULL);
306 if (ret == NO_ERROR) {
307 hw->waitAPIResult(evt, &apiResult);
308 ret = apiResult.status;
309 }
310 hw->unlockAPI();
311 hw->m_bPreviewStarted = true;
312 ALOGI("[KPI Perf] %s: X", __func__);
313 hw->m_perfLock.lock_rel();
314 return ret;
315 }
316
317 /*===========================================================================
318 * FUNCTION : stop_preview
319 *
320 * DESCRIPTION: stop preview
321 *
322 * PARAMETERS :
323 * @device : ptr to camera device struct
324 *
325 * RETURN : none
326 *==========================================================================*/
stop_preview(struct camera_device * device)327 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
328 {
329 ATRACE_CALL();
330 QCamera2HardwareInterface *hw =
331 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
332 if (!hw) {
333 ALOGE("NULL camera device");
334 return;
335 }
336 ALOGI("[KPI Perf] %s: E PROFILE_STOP_PREVIEW", __func__);
337 hw->m_perfLock.lock_acq();
338 hw->lockAPI();
339 qcamera_api_result_t apiResult;
340 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
341 if (ret == NO_ERROR) {
342 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult);
343 }
344 hw->unlockAPI();
345 hw->m_perfLock.lock_rel();
346 ALOGI("[KPI Perf] %s: X", __func__);
347 }
348
349 /*===========================================================================
350 * FUNCTION : preview_enabled
351 *
352 * DESCRIPTION: if preview is running
353 *
354 * PARAMETERS :
355 * @device : ptr to camera device struct
356 *
357 * RETURN : 1 -- running
358 * 0 -- not running
359 *==========================================================================*/
preview_enabled(struct camera_device * device)360 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
361 {
362 ATRACE_CALL();
363 int ret = NO_ERROR;
364 QCamera2HardwareInterface *hw =
365 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
366 if (!hw) {
367 ALOGE("NULL camera device");
368 return BAD_VALUE;
369 }
370
371 hw->lockAPI();
372 qcamera_api_result_t apiResult;
373 ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
374 if (ret == NO_ERROR) {
375 hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult);
376 ret = apiResult.enabled;
377 }
378 hw->unlockAPI();
379
380 return ret;
381 }
382
383 /*===========================================================================
384 * FUNCTION : store_meta_data_in_buffers
385 *
386 * DESCRIPTION: if need to store meta data in buffers for video frame
387 *
388 * PARAMETERS :
389 * @device : ptr to camera device struct
390 * @enable : flag if enable
391 *
392 * RETURN : int32_t type of status
393 * NO_ERROR -- success
394 * none-zero failure code
395 *==========================================================================*/
store_meta_data_in_buffers(struct camera_device * device,int enable)396 int QCamera2HardwareInterface::store_meta_data_in_buffers(
397 struct camera_device *device, int enable)
398 {
399 int ret = NO_ERROR;
400 QCamera2HardwareInterface *hw =
401 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
402 if (!hw) {
403 ALOGE("NULL camera device");
404 return BAD_VALUE;
405 }
406
407 hw->lockAPI();
408 qcamera_api_result_t apiResult;
409 ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable);
410 if (ret == NO_ERROR) {
411 hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult);
412 ret = apiResult.status;
413 }
414 hw->unlockAPI();
415
416 return ret;
417 }
418
419 /*===========================================================================
420 * FUNCTION : start_recording
421 *
422 * DESCRIPTION: start recording
423 *
424 * PARAMETERS :
425 * @device : ptr to camera device struct
426 *
427 * RETURN : int32_t type of status
428 * NO_ERROR -- success
429 * none-zero failure code
430 *==========================================================================*/
start_recording(struct camera_device * device)431 int QCamera2HardwareInterface::start_recording(struct camera_device *device)
432 {
433 ATRACE_CALL();
434 int ret = NO_ERROR;
435 QCamera2HardwareInterface *hw =
436 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
437 if (!hw) {
438 ALOGE("NULL camera device");
439 return BAD_VALUE;
440 }
441 ALOGI("[KPI Perf] %s: E PROFILE_START_RECORDING", __func__);
442 hw->lockAPI();
443 qcamera_api_result_t apiResult;
444 ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
445 if (ret == NO_ERROR) {
446 hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
447 ret = apiResult.status;
448 }
449 hw->unlockAPI();
450 hw->m_bRecordStarted = true;
451 ALOGI("[KPI Perf] %s: X", __func__);
452 return ret;
453 }
454
455 /*===========================================================================
456 * FUNCTION : stop_recording
457 *
458 * DESCRIPTION: stop recording
459 *
460 * PARAMETERS :
461 * @device : ptr to camera device struct
462 *
463 * RETURN : none
464 *==========================================================================*/
stop_recording(struct camera_device * device)465 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
466 {
467 ATRACE_CALL();
468 QCamera2HardwareInterface *hw =
469 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
470 if (!hw) {
471 ALOGE("NULL camera device");
472 return;
473 }
474 ALOGI("[KPI Perf] %s: E PROFILE_STOP_RECORDING", __func__);
475 hw->lockAPI();
476 qcamera_api_result_t apiResult;
477 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
478 if (ret == NO_ERROR) {
479 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
480 }
481 hw->unlockAPI();
482 ALOGI("[KPI Perf] %s: X", __func__);
483 }
484
485 /*===========================================================================
486 * FUNCTION : recording_enabled
487 *
488 * DESCRIPTION: if recording is running
489 *
490 * PARAMETERS :
491 * @device : ptr to camera device struct
492 *
493 * RETURN : 1 -- running
494 * 0 -- not running
495 *==========================================================================*/
recording_enabled(struct camera_device * device)496 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
497 {
498 ATRACE_CALL();
499 int ret = NO_ERROR;
500 QCamera2HardwareInterface *hw =
501 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
502 if (!hw) {
503 ALOGE("NULL camera device");
504 return BAD_VALUE;
505 }
506 hw->lockAPI();
507 qcamera_api_result_t apiResult;
508 ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
509 if (ret == NO_ERROR) {
510 hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
511 ret = apiResult.enabled;
512 }
513 hw->unlockAPI();
514
515 return ret;
516 }
517
518 /*===========================================================================
519 * FUNCTION : release_recording_frame
520 *
521 * DESCRIPTION: return recording frame back
522 *
523 * PARAMETERS :
524 * @device : ptr to camera device struct
525 * @opaque : ptr to frame to be returned
526 *
527 * RETURN : none
528 *==========================================================================*/
release_recording_frame(struct camera_device * device,const void * opaque)529 void QCamera2HardwareInterface::release_recording_frame(
530 struct camera_device *device, const void *opaque)
531 {
532 ATRACE_CALL();
533 QCamera2HardwareInterface *hw =
534 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
535 if (!hw) {
536 ALOGE("NULL camera device");
537 return;
538 }
539 if (!opaque) {
540 ALOGE("%s: Error!! Frame info is NULL", __func__);
541 return;
542 }
543 CDBG_HIGH("%s: E", __func__);
544 hw->lockAPI();
545 qcamera_api_result_t apiResult;
546 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
547 if (ret == NO_ERROR) {
548 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
549 }
550 hw->unlockAPI();
551 CDBG_HIGH("%s: X", __func__);
552 }
553
554 /*===========================================================================
555 * FUNCTION : auto_focus
556 *
557 * DESCRIPTION: start auto focus
558 *
559 * PARAMETERS :
560 * @device : ptr to camera device struct
561 *
562 * RETURN : int32_t type of status
563 * NO_ERROR -- success
564 * none-zero failure code
565 *==========================================================================*/
auto_focus(struct camera_device * device)566 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
567 {
568 ATRACE_INT("Camera:AutoFocus", 1);
569 int ret = NO_ERROR;
570 QCamera2HardwareInterface *hw =
571 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
572 if (!hw) {
573 ALOGE("NULL camera device");
574 return BAD_VALUE;
575 }
576 CDBG_HIGH("[KPI Perf] %s : E PROFILE_AUTO_FOCUS", __func__);
577 hw->lockAPI();
578 qcamera_api_result_t apiResult;
579 ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
580 if (ret == NO_ERROR) {
581 hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
582 ret = apiResult.status;
583 }
584 hw->unlockAPI();
585 CDBG_HIGH("[KPI Perf] %s : X", __func__);
586
587 return ret;
588 }
589
590 /*===========================================================================
591 * FUNCTION : cancel_auto_focus
592 *
593 * DESCRIPTION: cancel auto focus
594 *
595 * PARAMETERS :
596 * @device : ptr to camera device struct
597 *
598 * RETURN : int32_t type of status
599 * NO_ERROR -- success
600 * none-zero failure code
601 *==========================================================================*/
cancel_auto_focus(struct camera_device * device)602 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
603 {
604 ATRACE_CALL();
605 int ret = NO_ERROR;
606 QCamera2HardwareInterface *hw =
607 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
608 if (!hw) {
609 ALOGE("NULL camera device");
610 return BAD_VALUE;
611 }
612 ALOGE("[KPI Perf] %s : E PROFILE_CANCEL_AUTO_FOCUS", __func__);
613 hw->lockAPI();
614 qcamera_api_result_t apiResult;
615 ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
616 if (ret == NO_ERROR) {
617 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
618 ret = apiResult.status;
619 }
620 hw->unlockAPI();
621 CDBG_HIGH("[KPI Perf] %s : X", __func__);
622 return ret;
623 }
624
625 /*===========================================================================
626 * FUNCTION : take_picture
627 *
628 * DESCRIPTION: take picture
629 *
630 * PARAMETERS :
631 * @device : ptr to camera device struct
632 *
633 * RETURN : int32_t type of status
634 * NO_ERROR -- success
635 * none-zero failure code
636 *==========================================================================*/
take_picture(struct camera_device * device)637 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
638 {
639 ATRACE_CALL();
640 int ret = NO_ERROR;
641 QCamera2HardwareInterface *hw =
642 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
643 if (!hw) {
644 ALOGE("NULL camera device");
645 return BAD_VALUE;
646 }
647 ALOGI("[KPI Perf] %s: E PROFILE_TAKE_PICTURE", __func__);
648 hw->lockAPI();
649 if (!hw->mLongshotEnabled) {
650 hw->m_perfLock.lock_acq();
651 }
652 qcamera_api_result_t apiResult;
653
654 /** Added support for Retro-active Frames:
655 * takePicture() is called before preparing Snapshot to indicate the
656 * mm-camera-channel to pick up legacy frames even
657 * before LED estimation is triggered.
658 */
659
660 CDBG_HIGH("%s: [ZSL Retro]: numRetroSnap %d, isLiveSnap %d, isZSL %d, isHDR %d",
661 __func__, hw->mParameters.getNumOfRetroSnapshots(),
662 hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode());
663
664 // Check for Retro-active Frames
665 if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
666 !hw->isLiveSnapshot() && hw->isZSLMode() &&
667 !hw->isHDRMode() && !hw->isLongshotEnabled()) {
668 // Set Retro Picture Mode
669 hw->setRetroPicture(1);
670 hw->m_bLedAfAecLock = 0;
671 CDBG_HIGH("%s: [ZSL Retro] mode", __func__);
672
673 /* Call take Picture for total number of snapshots required.
674 This includes the number of retro frames and normal frames */
675 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
676 if (ret == NO_ERROR) {
677 // Wait for retro frames, before calling prepare snapshot
678 CDBG_HIGH("%s:[ZSL Retro] Wait for Retro frames to be done", __func__);
679 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
680 ret = apiResult.status;
681 }
682
683
684 // Start Preparing for normal Frames
685 CDBG_HIGH("%s: [ZSL Retro] Start Prepare Snapshot", __func__);
686 /* Prepare snapshot in case LED needs to be flashed */
687 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
688 if (ret == NO_ERROR) {
689 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
690 ret = apiResult.status;
691 CDBG_HIGH("%s: [ZSL Retro] Prep Snapshot done", __func__);
692 }
693 hw->mPrepSnapRun = true;
694 }
695 else {
696 hw->setRetroPicture(0);
697 CDBG_HIGH("%s: [ZSL Retro] Normal Pic Taking Mode", __func__);
698
699 CDBG_HIGH("%s: [ZSL Retro] Start Prepare Snapshot", __func__);
700 /* Prepare snapshot in case LED needs to be flashed */
701 if (hw->mFlashNeeded == 1 || hw->mParameters.isChromaFlashEnabled()) {
702 // Start Preparing for normal Frames
703 CDBG_HIGH("%s: [ZSL Retro] Start Prepare Snapshot", __func__);
704 /* Prepare snapshot in case LED needs to be flashed */
705 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
706 if (ret == NO_ERROR) {
707 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
708 ret = apiResult.status;
709 CDBG_HIGH("%s: [ZSL Retro] Prep Snapshot done", __func__);
710
711 }
712 hw->mPrepSnapRun = true;
713 }
714 /* Regardless what the result value for prepare_snapshot,
715 * go ahead with capture anyway. Just like the way autofocus
716 * is handled in capture case. */
717 /* capture */
718 CDBG_HIGH("%s: [ZSL Retro] Capturing normal frames", __func__);
719 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
720 if (ret == NO_ERROR) {
721 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
722 ret = apiResult.status;
723 }
724 }
725 hw->unlockAPI();
726 ALOGI("[KPI Perf] %s: X", __func__);
727 return ret;
728 }
729
730 /*===========================================================================
731 * FUNCTION : cancel_picture
732 *
733 * DESCRIPTION: cancel current take picture request
734 *
735 * PARAMETERS :
736 * @device : ptr to camera device struct
737 *
738 * RETURN : int32_t type of status
739 * NO_ERROR -- success
740 * none-zero failure code
741 *==========================================================================*/
cancel_picture(struct camera_device * device)742 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
743 {
744 ATRACE_CALL();
745 int ret = NO_ERROR;
746 QCamera2HardwareInterface *hw =
747 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
748 if (!hw) {
749 ALOGE("NULL camera device");
750 return BAD_VALUE;
751 }
752 hw->lockAPI();
753 qcamera_api_result_t apiResult;
754 ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
755 if (ret == NO_ERROR) {
756 hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
757 ret = apiResult.status;
758 }
759 hw->unlockAPI();
760
761 return ret;
762 }
763
764 /*===========================================================================
765 * FUNCTION : set_parameters
766 *
767 * DESCRIPTION: set camera parameters
768 *
769 * PARAMETERS :
770 * @device : ptr to camera device struct
771 * @parms : string of packed parameters
772 *
773 * RETURN : int32_t type of status
774 * NO_ERROR -- success
775 * none-zero failure code
776 *==========================================================================*/
set_parameters(struct camera_device * device,const char * parms)777 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
778 const char *parms)
779 {
780 ATRACE_CALL();
781 int ret = NO_ERROR;
782 QCamera2HardwareInterface *hw =
783 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
784 if (!hw) {
785 ALOGE("NULL camera device");
786 return BAD_VALUE;
787 }
788 hw->lockAPI();
789 qcamera_api_result_t apiResult;
790 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
791 if (ret == NO_ERROR) {
792 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
793 ret = apiResult.status;
794 }
795 hw->unlockAPI();
796
797 return ret;
798 }
799
800 /*===========================================================================
801 * FUNCTION : get_parameters
802 *
803 * DESCRIPTION: query camera parameters
804 *
805 * PARAMETERS :
806 * @device : ptr to camera device struct
807 *
808 * RETURN : packed parameters in a string
809 *==========================================================================*/
get_parameters(struct camera_device * device)810 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
811 {
812 ATRACE_CALL();
813 char *ret = NULL;
814 QCamera2HardwareInterface *hw =
815 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
816 if (!hw) {
817 ALOGE("NULL camera device");
818 return NULL;
819 }
820 hw->lockAPI();
821 qcamera_api_result_t apiResult;
822 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
823 if (rc == NO_ERROR) {
824 hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
825 ret = apiResult.params;
826 }
827 hw->unlockAPI();
828
829 return ret;
830 }
831
832 /*===========================================================================
833 * FUNCTION : put_parameters
834 *
835 * DESCRIPTION: return camera parameters string back to HAL
836 *
837 * PARAMETERS :
838 * @device : ptr to camera device struct
839 * @parm : ptr to parameter string to be returned
840 *
841 * RETURN : none
842 *==========================================================================*/
put_parameters(struct camera_device * device,char * parm)843 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
844 char *parm)
845 {
846 ATRACE_CALL();
847 QCamera2HardwareInterface *hw =
848 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
849 if (!hw) {
850 ALOGE("NULL camera device");
851 return;
852 }
853 hw->lockAPI();
854 qcamera_api_result_t apiResult;
855 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
856 if (ret == NO_ERROR) {
857 hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
858 }
859 hw->unlockAPI();
860 }
861
862 /*===========================================================================
863 * FUNCTION : send_command
864 *
865 * DESCRIPTION: command to be executed
866 *
867 * PARAMETERS :
868 * @device : ptr to camera device struct
869 * @cmd : cmd to be executed
870 * @arg1 : ptr to optional argument1
871 * @arg2 : ptr to optional argument2
872 *
873 * RETURN : int32_t type of status
874 * NO_ERROR -- success
875 * none-zero failure code
876 *==========================================================================*/
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)877 int QCamera2HardwareInterface::send_command(struct camera_device *device,
878 int32_t cmd,
879 int32_t arg1,
880 int32_t arg2)
881 {
882 ATRACE_CALL();
883 int ret = NO_ERROR;
884 QCamera2HardwareInterface *hw =
885 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
886 if (!hw) {
887 ALOGE("NULL camera device");
888 return BAD_VALUE;
889 }
890
891 qcamera_sm_evt_command_payload_t payload;
892 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
893 payload.cmd = cmd;
894 payload.arg1 = arg1;
895 payload.arg2 = arg2;
896 hw->lockAPI();
897 qcamera_api_result_t apiResult;
898 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
899 if (ret == NO_ERROR) {
900 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
901 ret = apiResult.status;
902 }
903 hw->unlockAPI();
904
905 return ret;
906 }
907
908 /*===========================================================================
909 * FUNCTION : release
910 *
911 * DESCRIPTION: release camera resource
912 *
913 * PARAMETERS :
914 * @device : ptr to camera device struct
915 *
916 * RETURN : none
917 *==========================================================================*/
release(struct camera_device * device)918 void QCamera2HardwareInterface::release(struct camera_device *device)
919 {
920 ATRACE_CALL();
921 QCamera2HardwareInterface *hw =
922 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
923 if (!hw) {
924 ALOGE("NULL camera device");
925 return;
926 }
927 hw->lockAPI();
928 qcamera_api_result_t apiResult;
929 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
930 if (ret == NO_ERROR) {
931 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
932 }
933 hw->unlockAPI();
934 }
935
936 /*===========================================================================
937 * FUNCTION : dump
938 *
939 * DESCRIPTION: dump camera status
940 *
941 * PARAMETERS :
942 * @device : ptr to camera device struct
943 * @fd : fd for status to be dumped to
944 *
945 * RETURN : int32_t type of status
946 * NO_ERROR -- success
947 * none-zero failure code
948 *==========================================================================*/
dump(struct camera_device * device,int fd)949 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
950 {
951 int ret = NO_ERROR;
952
953 //Log level property is read when "adb shell dumpsys media.camera" is
954 //called so that the log level can be controlled without restarting
955 //media server
956 getLogLevel();
957 QCamera2HardwareInterface *hw =
958 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
959 if (!hw) {
960 ALOGE("NULL camera device");
961 return BAD_VALUE;
962 }
963 hw->lockAPI();
964 qcamera_api_result_t apiResult;
965 ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
966 if (ret == NO_ERROR) {
967 hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
968 ret = apiResult.status;
969 }
970 hw->unlockAPI();
971
972 return ret;
973 }
974
975 /*===========================================================================
976 * FUNCTION : close_camera_device
977 *
978 * DESCRIPTION: close camera device
979 *
980 * PARAMETERS :
981 * @device : ptr to camera device struct
982 *
983 * RETURN : int32_t type of status
984 * NO_ERROR -- success
985 * none-zero failure code
986 *==========================================================================*/
close_camera_device(hw_device_t * hw_dev)987 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
988 {
989 ATRACE_CALL();
990 int ret = NO_ERROR;
991 ALOGI("[KPI Perf] %s: E",__func__);
992 QCamera2HardwareInterface *hw =
993 reinterpret_cast<QCamera2HardwareInterface *>(
994 reinterpret_cast<camera_device_t *>(hw_dev)->priv);
995 if (!hw) {
996 ALOGE("%s: NULL camera device", __func__);
997 return BAD_VALUE;
998 }
999 delete hw;
1000 ALOGI("[KPI Perf] %s: X",__func__);
1001 return ret;
1002 }
1003
1004 /*===========================================================================
1005 * FUNCTION : register_face_image
1006 *
1007 * DESCRIPTION: register a face image into imaging lib for face authenticatio/
1008 * face recognition
1009 *
1010 * PARAMETERS :
1011 * @device : ptr to camera device struct
1012 * @img_ptr : ptr to image buffer
1013 * @config : ptr to config about input image, i.e., format, dimension, and etc.
1014 *
1015 * RETURN : >=0 unique ID of face registerd.
1016 * <0 failure.
1017 *==========================================================================*/
register_face_image(struct camera_device * device,void * img_ptr,cam_pp_offline_src_config_t * config)1018 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
1019 void *img_ptr,
1020 cam_pp_offline_src_config_t *config)
1021 {
1022 ATRACE_CALL();
1023 int ret = NO_ERROR;
1024 QCamera2HardwareInterface *hw =
1025 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1026 if (!hw) {
1027 ALOGE("NULL camera device");
1028 return BAD_VALUE;
1029 }
1030 qcamera_sm_evt_reg_face_payload_t payload;
1031 memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
1032 payload.img_ptr = img_ptr;
1033 payload.config = config;
1034 hw->lockAPI();
1035 qcamera_api_result_t apiResult;
1036 ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
1037 if (ret == NO_ERROR) {
1038 hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
1039 ret = apiResult.handle;
1040 }
1041 hw->unlockAPI();
1042
1043 return ret;
1044 }
1045
1046 /*===========================================================================
1047 * FUNCTION : QCamera2HardwareInterface
1048 *
1049 * DESCRIPTION: constructor of QCamera2HardwareInterface
1050 *
1051 * PARAMETERS :
1052 * @cameraId : camera ID
1053 *
1054 * RETURN : none
1055 *==========================================================================*/
QCamera2HardwareInterface(uint32_t cameraId)1056 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
1057 : mCameraId(cameraId),
1058 mCameraHandle(NULL),
1059 mCameraOpened(false),
1060 mPreviewWindow(NULL),
1061 mMsgEnabled(0),
1062 mStoreMetaDataInFrame(0),
1063 m_stateMachine(this),
1064 m_smThreadActive(true),
1065 m_postprocessor(this),
1066 m_thermalAdapter(QCameraThermalAdapter::getInstance()),
1067 m_cbNotifier(this),
1068 m_bPreviewStarted(false),
1069 m_bRecordStarted(false),
1070 m_currentFocusState(CAM_AF_SCANNING),
1071 mDumpFrmCnt(0U),
1072 mDumpSkipCnt(0U),
1073 mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
1074 mCancelAutoFocus(false),
1075 m_HDRSceneEnabled(false),
1076 mLongshotEnabled(false),
1077 m_max_pic_width(0),
1078 m_max_pic_height(0),
1079 mLiveSnapshotThread(0),
1080 mIntPicThread(0),
1081 mFlashNeeded(false),
1082 mDeviceRotation(0U),
1083 mCaptureRotation(0U),
1084 mJpegExifRotation(0U),
1085 mUseJpegExifRotation(false),
1086 mIs3ALocked(false),
1087 mPrepSnapRun(false),
1088 mZoomLevel(0),
1089 mVFrameCount(0),
1090 mVLastFrameCount(0),
1091 mVLastFpsTime(0),
1092 mVFps(0),
1093 mPFrameCount(0),
1094 mPLastFrameCount(0),
1095 mPLastFpsTime(0),
1096 mPFps(0),
1097 m_bIntJpegEvtPending(false),
1098 m_bIntRawEvtPending(false),
1099 mSnapshotJob(-1),
1100 mPostviewJob(-1),
1101 mMetadataJob(-1),
1102 mReprocJob(-1),
1103 mRawdataJob(-1),
1104 mOutputCount(0),
1105 mInputCount(0),
1106 mAdvancedCaptureConfigured(false),
1107 mHDRBracketingEnabled(false)
1108 {
1109 getLogLevel();
1110 ATRACE_CALL();
1111 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1112 mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1113 mCameraDevice.common.close = close_camera_device;
1114 mCameraDevice.ops = &mCameraOps;
1115 mCameraDevice.priv = this;
1116
1117 pthread_mutex_init(&m_lock, NULL);
1118 pthread_cond_init(&m_cond, NULL);
1119
1120 m_apiResultList = NULL;
1121
1122 pthread_mutex_init(&m_evtLock, NULL);
1123 pthread_cond_init(&m_evtCond, NULL);
1124 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1125
1126 pthread_mutex_init(&m_parm_lock, NULL);
1127
1128 pthread_mutex_init(&m_int_lock, NULL);
1129 pthread_cond_init(&m_int_cond, NULL);
1130
1131 memset(m_channels, 0, sizeof(m_channels));
1132 memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
1133
1134 memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
1135
1136 memset(mDeffOngoingJobs, 0, sizeof(mDeffOngoingJobs));
1137 m_perfLock.lock_init();
1138
1139 mDefferedWorkThread.launch(defferedWorkRoutine, this);
1140 mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1141 }
1142
1143 /*===========================================================================
1144 * FUNCTION : ~QCamera2HardwareInterface
1145 *
1146 * DESCRIPTION: destructor of QCamera2HardwareInterface
1147 *
1148 * PARAMETERS : none
1149 *
1150 * RETURN : none
1151 *==========================================================================*/
~QCamera2HardwareInterface()1152 QCamera2HardwareInterface::~QCamera2HardwareInterface()
1153 {
1154 mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1155 mDefferedWorkThread.exit();
1156
1157 m_perfLock.lock_acq();
1158 lockAPI();
1159 m_smThreadActive = false;
1160 unlockAPI();
1161 m_stateMachine.releaseThread();
1162 closeCamera();
1163 m_perfLock.lock_rel();
1164 m_perfLock.lock_deinit();
1165 pthread_mutex_destroy(&m_lock);
1166 pthread_cond_destroy(&m_cond);
1167 pthread_mutex_destroy(&m_evtLock);
1168 pthread_cond_destroy(&m_evtCond);
1169 pthread_mutex_destroy(&m_parm_lock);
1170 pthread_mutex_destroy(&m_int_lock);
1171 pthread_cond_destroy(&m_int_cond);
1172 }
1173
1174 /*===========================================================================
1175 * FUNCTION : openCamera
1176 *
1177 * DESCRIPTION: open camera
1178 *
1179 * PARAMETERS :
1180 * @hw_device : double ptr for camera device struct
1181 *
1182 * RETURN : int32_t type of status
1183 * NO_ERROR -- success
1184 * none-zero failure code
1185 *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1186 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1187 {
1188 ATRACE_CALL();
1189 int rc = NO_ERROR;
1190 if (mCameraOpened) {
1191 *hw_device = NULL;
1192 return PERMISSION_DENIED;
1193 }
1194 ALOGI("[KPI Perf] %s: E PROFILE_OPEN_CAMERA camera id %d",
1195 __func__,mCameraId);
1196 m_perfLock.lock_acq();
1197 rc = openCamera();
1198 if (rc == NO_ERROR){
1199 *hw_device = &mCameraDevice.common;
1200 if (m_thermalAdapter.init(this) != 0) {
1201 ALOGE("Init thermal adapter failed");
1202 }
1203 }
1204 else
1205 *hw_device = NULL;
1206
1207 ALOGI("[KPI Perf] %s: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
1208 __func__,mCameraId, rc);
1209
1210 m_perfLock.lock_rel();
1211 return rc;
1212 }
1213
1214 /*===========================================================================
1215 * FUNCTION : openCamera
1216 *
1217 * DESCRIPTION: open camera
1218 *
1219 * PARAMETERS : none
1220 *
1221 * RETURN : int32_t type of status
1222 * NO_ERROR -- success
1223 * none-zero failure code
1224 *==========================================================================*/
openCamera()1225 int QCamera2HardwareInterface::openCamera()
1226 {
1227 int32_t l_curr_width = 0;
1228 int32_t l_curr_height = 0;
1229 m_max_pic_width = 0;
1230 m_max_pic_height = 0;
1231 size_t i;
1232 int32_t rc = 0;
1233
1234 if (mCameraHandle) {
1235 ALOGE("Failure: Camera already opened");
1236 return ALREADY_EXISTS;
1237 }
1238 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1239 if (rc) {
1240 ALOGE("camera_open failed. rc = %d, mCameraHandle = %p", rc, mCameraHandle);
1241 return rc;
1242 }
1243 if (NULL == gCamCaps[mCameraId])
1244 initCapabilities(mCameraId,mCameraHandle);
1245
1246 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1247 camEvtHandle,
1248 (void *) this);
1249
1250 /* get max pic size for jpeg work buf calculation*/
1251 for(i = 0; i < gCamCaps[mCameraId]->picture_sizes_tbl_cnt - 1; i++)
1252 {
1253 l_curr_width = gCamCaps[mCameraId]->picture_sizes_tbl[i].width;
1254 l_curr_height = gCamCaps[mCameraId]->picture_sizes_tbl[i].height;
1255
1256 if ((l_curr_width * l_curr_height) >
1257 (m_max_pic_width * m_max_pic_height)) {
1258 m_max_pic_width = l_curr_width;
1259 m_max_pic_height = l_curr_height;
1260 }
1261 }
1262
1263 rc = m_postprocessor.init(jpegEvtHandle, this);
1264 if (rc != 0) {
1265 ALOGE("Init Postprocessor failed");
1266 mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1267 mCameraHandle = NULL;
1268 return UNKNOWN_ERROR;
1269 }
1270
1271 // update padding info from jpeg
1272 cam_padding_info_t padding_info;
1273 m_postprocessor.getJpegPaddingReq(padding_info);
1274 if (gCamCaps[mCameraId]->padding_info.width_padding < padding_info.width_padding) {
1275 gCamCaps[mCameraId]->padding_info.width_padding = padding_info.width_padding;
1276 }
1277 if (gCamCaps[mCameraId]->padding_info.height_padding < padding_info.height_padding) {
1278 gCamCaps[mCameraId]->padding_info.height_padding = padding_info.height_padding;
1279 }
1280 if (gCamCaps[mCameraId]->padding_info.plane_padding < padding_info.plane_padding) {
1281 gCamCaps[mCameraId]->padding_info.plane_padding = padding_info.plane_padding;
1282 }
1283
1284 mParameters.init(gCamCaps[mCameraId], mCameraHandle, this);
1285 mParameters.setMinPpMask(gCamCaps[mCameraId]->min_required_pp_mask);
1286
1287 mCameraOpened = true;
1288
1289 return NO_ERROR;
1290 }
1291
1292 /*===========================================================================
1293 * FUNCTION : closeCamera
1294 *
1295 * DESCRIPTION: close camera
1296 *
1297 * PARAMETERS : none
1298 *
1299 * RETURN : int32_t type of status
1300 * NO_ERROR -- success
1301 * none-zero failure code
1302 *==========================================================================*/
closeCamera()1303 int QCamera2HardwareInterface::closeCamera()
1304 {
1305 int rc = NO_ERROR;
1306 int i;
1307
1308 if (!mCameraOpened) {
1309 return NO_ERROR;
1310 }
1311 ALOGI("[KPI Perf] %s: E PROFILE_CLOSE_CAMERA camera id %d",
1312 __func__, mCameraId);
1313
1314 pthread_mutex_lock(&m_parm_lock);
1315
1316 // set open flag to false
1317 mCameraOpened = false;
1318
1319 // Reset Stream config info
1320 mParameters.setStreamConfigure(false, false, true);
1321
1322 // deinit Parameters
1323 mParameters.deinit();
1324
1325 pthread_mutex_unlock(&m_parm_lock);
1326
1327 // exit notifier
1328 m_cbNotifier.exit();
1329
1330 // stop and deinit postprocessor
1331 waitDefferedWork(mReprocJob);
1332 m_postprocessor.stop();
1333 m_postprocessor.deinit();
1334
1335 //free all pending api results here
1336 if(m_apiResultList != NULL) {
1337 api_result_list *apiResultList = m_apiResultList;
1338 api_result_list *apiResultListNext;
1339 while (apiResultList != NULL) {
1340 apiResultListNext = apiResultList->next;
1341 free(apiResultList);
1342 apiResultList = apiResultListNext;
1343 }
1344 }
1345
1346 m_thermalAdapter.deinit();
1347
1348 // delete all channels if not already deleted
1349 for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
1350 if (m_channels[i] != NULL) {
1351 m_channels[i]->stop();
1352 delete m_channels[i];
1353 m_channels[i] = NULL;
1354 }
1355 }
1356
1357 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1358 mCameraHandle = NULL;
1359 ALOGI("[KPI Perf] %s: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
1360 __func__, mCameraId, rc);
1361
1362 return rc;
1363 }
1364
1365 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
1366
1367 /*===========================================================================
1368 * FUNCTION : initCapabilities
1369 *
1370 * DESCRIPTION: initialize camera capabilities in static data struct
1371 *
1372 * PARAMETERS :
1373 * @cameraId : camera Id
1374 *
1375 * RETURN : int32_t type of status
1376 * NO_ERROR -- success
1377 * none-zero failure code
1378 *==========================================================================*/
initCapabilities(uint32_t cameraId,mm_camera_vtbl_t * cameraHandle)1379 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
1380 mm_camera_vtbl_t *cameraHandle)
1381 {
1382 ATRACE_CALL();
1383 int rc = NO_ERROR;
1384 QCameraHeapMemory *capabilityHeap = NULL;
1385
1386 /* Allocate memory for capability buffer */
1387 capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1388 rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
1389 if(rc != OK) {
1390 ALOGE("%s: No memory for cappability", __func__);
1391 goto allocate_failed;
1392 }
1393
1394 /* Map memory for capability buffer */
1395 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
1396 rc = cameraHandle->ops->map_buf(cameraHandle->camera_handle,
1397 CAM_MAPPING_BUF_TYPE_CAPABILITY,
1398 capabilityHeap->getFd(0),
1399 sizeof(cam_capability_t));
1400 if(rc < 0) {
1401 ALOGE("%s: failed to map capability buffer", __func__);
1402 goto map_failed;
1403 }
1404
1405 /* Query Capability */
1406 rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
1407 if(rc < 0) {
1408 ALOGE("%s: failed to query capability",__func__);
1409 goto query_failed;
1410 }
1411 gCamCaps[cameraId] = (cam_capability_t *)malloc(sizeof(cam_capability_t));
1412 if (!gCamCaps[cameraId]) {
1413 ALOGE("%s: out of memory", __func__);
1414 goto query_failed;
1415 }
1416 memcpy(gCamCaps[cameraId], DATA_PTR(capabilityHeap,0),
1417 sizeof(cam_capability_t));
1418
1419 rc = NO_ERROR;
1420
1421 query_failed:
1422 cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
1423 CAM_MAPPING_BUF_TYPE_CAPABILITY);
1424 map_failed:
1425 capabilityHeap->deallocate();
1426 delete capabilityHeap;
1427 allocate_failed:
1428 return rc;
1429 }
1430
1431 /*===========================================================================
1432 * FUNCTION : getCapabilities
1433 *
1434 * DESCRIPTION: query camera capabilities
1435 *
1436 * PARAMETERS :
1437 * @cameraId : camera Id
1438 * @info : camera info struct to be filled in with camera capabilities
1439 *
1440 * RETURN : int type of status
1441 * NO_ERROR -- success
1442 * none-zero failure code
1443 *==========================================================================*/
getCapabilities(uint32_t cameraId,struct camera_info * info)1444 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
1445 struct camera_info *info)
1446 {
1447 ATRACE_CALL();
1448 int rc = NO_ERROR;
1449 struct camera_info *p_info;
1450 pthread_mutex_lock(&g_camlock);
1451 p_info = get_cam_info(cameraId);
1452 p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
1453 p_info->static_camera_characteristics = NULL;
1454 memcpy(info, p_info, sizeof (struct camera_info));
1455 pthread_mutex_unlock(&g_camlock);
1456 return rc;
1457 }
1458
1459 /*===========================================================================
1460 * FUNCTION : getCamHalCapabilities
1461 *
1462 * DESCRIPTION: get the HAL capabilities structure
1463 *
1464 * PARAMETERS :
1465 * @cameraId : camera Id
1466 *
1467 * RETURN : capability structure of respective camera
1468 *
1469 *==========================================================================*/
getCamHalCapabilities()1470 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
1471 {
1472 return gCamCaps[mCameraId];
1473 }
1474
1475 /*===========================================================================
1476 * FUNCTION : getBufNumRequired
1477 *
1478 * DESCRIPTION: return number of stream buffers needed for given stream type
1479 *
1480 * PARAMETERS :
1481 * @stream_type : type of stream
1482 *
1483 * RETURN : number of buffers needed
1484 *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)1485 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
1486 {
1487 int bufferCnt = 0;
1488 int minCaptureBuffers = mParameters.getNumOfSnapshots();
1489 char value[PROPERTY_VALUE_MAX];
1490 bool raw_yuv = false;
1491
1492 int zslQBuffers = mParameters.getZSLQueueDepth();
1493
1494 int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
1495 CAMERA_MIN_JPEG_ENCODING_BUFFERS;
1496
1497 int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
1498 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1499 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1500 mParameters.getNumOfExtraBuffersForImageProc() +
1501 EXTRA_ZSL_PREVIEW_STREAM_BUF;
1502
1503 int minUndequeCount = 0;
1504 if (!isNoDisplayMode()) {
1505 if(mPreviewWindow != NULL) {
1506 if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
1507 != 0) {
1508 ALOGE("get_min_undequeued_buffer_count failed");
1509 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
1510 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
1511 minUndequeCount = 2;
1512 }
1513 } else {
1514 //preview window might not be set at this point. So, query directly
1515 //from BufferQueue implementation of gralloc buffers.
1516 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
1517 //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
1518 minUndequeCount = 2;
1519 }
1520 }
1521
1522 // Get buffer count for the particular stream type
1523 switch (stream_type) {
1524 case CAM_STREAM_TYPE_PREVIEW:
1525 {
1526 if (mParameters.isZSLMode()) {
1527 // We need to add two extra streming buffers to add
1528 // flexibility in forming matched super buf in ZSL queue.
1529 // with number being 'zslQBuffers + minCircularBufNum'
1530 // we see preview buffers sometimes get dropped at CPP
1531 // and super buf is not forming in ZSL Q for long time.
1532
1533 bufferCnt = zslQBuffers + minCircularBufNum +
1534 mParameters.getNumOfExtraBuffersForImageProc() +
1535 EXTRA_ZSL_PREVIEW_STREAM_BUF +
1536 mParameters.getNumOfExtraBuffersForPreview();
1537 } else {
1538 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
1539 mParameters.getMaxUnmatchedFramesInQueue() +
1540 mParameters.getNumOfExtraBuffersForPreview();
1541 }
1542 bufferCnt += minUndequeCount;
1543 }
1544 break;
1545 case CAM_STREAM_TYPE_POSTVIEW:
1546 {
1547 bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER +
1548 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1549 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1550 mParameters.getNumOfExtraBuffersForImageProc();
1551
1552 if (bufferCnt > maxStreamBuf) {
1553 bufferCnt = maxStreamBuf;
1554 }
1555 bufferCnt += minUndequeCount;
1556 }
1557 break;
1558 case CAM_STREAM_TYPE_SNAPSHOT:
1559 {
1560 if (mParameters.isZSLMode() || mLongshotEnabled) {
1561 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
1562 !mLongshotEnabled) {
1563 // Single ZSL snapshot case
1564 bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
1565 mParameters.getNumOfExtraBuffersForImageProc();
1566 }
1567 else {
1568 // ZSL Burst or Longshot case
1569 bufferCnt = zslQBuffers + minCircularBufNum +
1570 mParameters.getNumOfExtraBuffersForImageProc();
1571 }
1572 } else {
1573 bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER +
1574 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1575 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1576 mParameters.getNumOfExtraBuffersForImageProc();
1577
1578 if (bufferCnt > maxStreamBuf) {
1579 bufferCnt = maxStreamBuf;
1580 }
1581 }
1582 }
1583 break;
1584 case CAM_STREAM_TYPE_RAW:
1585 property_get("persist.camera.raw_yuv", value, "0");
1586 raw_yuv = atoi(value) > 0 ? true : false;
1587
1588 if (isRdiMode() || raw_yuv) {
1589 CDBG_HIGH("RDI_DEBUG %s[%d]: CAM_STREAM_TYPE_RAW",
1590 __func__, __LINE__);
1591 bufferCnt = zslQBuffers + minCircularBufNum;
1592 } else if (mParameters.isZSLMode()) {
1593 bufferCnt = zslQBuffers + minCircularBufNum;
1594 } else {
1595 bufferCnt = minCaptureBuffers*CAMERA_PPROC_OUT_BUFFER_MULTIPLIER +
1596 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1597 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1598 mParameters.getNumOfExtraBuffersForImageProc();
1599
1600 if (bufferCnt > maxStreamBuf) {
1601 bufferCnt = maxStreamBuf;
1602 }
1603 }
1604 break;
1605 case CAM_STREAM_TYPE_VIDEO:
1606 {
1607 if (mParameters.getBufBatchCount()) {
1608 bufferCnt = CAMERA_MIN_VIDEO_BATCH_BUFFERS;
1609 } else {
1610 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
1611 }
1612
1613 bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
1614 //if its 4K encoding usecase, then add extra buffer
1615 cam_dimension_t dim;
1616 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
1617 if (is4k2kResolution(&dim)) {
1618 //get additional buffer count
1619 property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
1620 bufferCnt += atoi(value);
1621 }
1622 ALOGI("Buffer count is %d, width / height (%d/%d) ", bufferCnt, dim.width, dim.height);
1623 }
1624 break;
1625 case CAM_STREAM_TYPE_METADATA:
1626 {
1627 if (mParameters.isZSLMode()) {
1628 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
1629 bufferCnt = zslQBuffers + minCircularBufNum +
1630 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1631 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1632 mParameters.getNumOfExtraBuffersForImageProc() +
1633 EXTRA_ZSL_PREVIEW_STREAM_BUF;
1634 } else {
1635 bufferCnt = minCaptureBuffers +
1636 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
1637 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
1638 mParameters.getMaxUnmatchedFramesInQueue() +
1639 CAMERA_MIN_STREAMING_BUFFERS +
1640 mParameters.getNumOfExtraBuffersForImageProc();
1641
1642 if (bufferCnt > zslQBuffers + minCircularBufNum) {
1643 bufferCnt = zslQBuffers + minCircularBufNum;
1644 }
1645 }
1646 }
1647 break;
1648 case CAM_STREAM_TYPE_OFFLINE_PROC:
1649 {
1650 bufferCnt = minCaptureBuffers;
1651 // One of the ubifocus buffers is miscellaneous buffer
1652 if (mParameters.isUbiRefocus()) {
1653 bufferCnt -= 1;
1654 }
1655 if (mLongshotEnabled) {
1656 char prop[PROPERTY_VALUE_MAX];
1657 memset(prop, 0, sizeof(prop));
1658 property_get("persist.camera.longshot.stages", prop, "0");
1659 int longshotStages = atoi(prop);
1660 if (longshotStages > 0 && longshotStages < CAMERA_LONGSHOT_STAGES) {
1661 bufferCnt = longshotStages;
1662 }
1663 else {
1664 bufferCnt = CAMERA_LONGSHOT_STAGES;
1665 }
1666 }
1667 }
1668 break;
1669 case CAM_STREAM_TYPE_ANALYSIS:
1670 case CAM_STREAM_TYPE_DEFAULT:
1671 case CAM_STREAM_TYPE_MAX:
1672 default:
1673 bufferCnt = 0;
1674 break;
1675 }
1676
1677 if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
1678 ALOGE("%s: Buffer count %d for stream type %d exceeds limit %d",
1679 __func__, bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
1680 return CAM_MAX_NUM_BUFS_PER_STREAM;
1681 }
1682
1683 return (uint8_t)bufferCnt;
1684 }
1685
1686 /*===========================================================================
1687 * FUNCTION : allocateStreamBuf
1688 *
1689 * DESCRIPTION: alocate stream buffers
1690 *
1691 * PARAMETERS :
1692 * @stream_type : type of stream
1693 * @size : size of buffer
1694 * @stride : stride of buffer
1695 * @scanline : scanline of buffer
1696 * @bufferCnt : [IN/OUT] minimum num of buffers to be allocated.
1697 * could be modified during allocation if more buffers needed
1698 *
1699 * RETURN : ptr to a memory obj that holds stream buffers.
1700 * NULL if failed
1701 *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,size_t size,int stride,int scanline,uint8_t & bufferCnt)1702 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
1703 cam_stream_type_t stream_type, size_t size, int stride, int scanline,
1704 uint8_t &bufferCnt)
1705 {
1706 int rc = NO_ERROR;
1707 QCameraMemory *mem = NULL;
1708 bool bCachedMem = QCAMERA_ION_USE_CACHE;
1709 bool bPoolMem = false;
1710 char value[PROPERTY_VALUE_MAX];
1711 property_get("persist.camera.mem.usepool", value, "1");
1712 if (atoi(value) == 1) {
1713 bPoolMem = true;
1714 }
1715
1716 // Allocate stream buffer memory object
1717 switch (stream_type) {
1718 case CAM_STREAM_TYPE_PREVIEW:
1719 {
1720 if (isNoDisplayMode()) {
1721 mem = new QCameraStreamMemory(mGetMemory,
1722 bCachedMem,
1723 (bPoolMem) ? &m_memoryPool : NULL,
1724 stream_type);
1725 } else {
1726 cam_dimension_t dim;
1727 QCameraGrallocMemory *grallocMemory =
1728 new QCameraGrallocMemory(mGetMemory);
1729
1730 mParameters.getStreamDimension(stream_type, dim);
1731 if (grallocMemory)
1732 grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
1733 dim.height, stride, scanline,
1734 mParameters.getPreviewHalPixelFormat());
1735 mem = grallocMemory;
1736 }
1737 }
1738 break;
1739 case CAM_STREAM_TYPE_POSTVIEW:
1740 {
1741 if (isNoDisplayMode() || isPreviewRestartEnabled()) {
1742 mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
1743 } else {
1744 cam_dimension_t dim;
1745 QCameraGrallocMemory *grallocMemory =
1746 new QCameraGrallocMemory(mGetMemory);
1747
1748 mParameters.getStreamDimension(stream_type, dim);
1749 if (grallocMemory)
1750 grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
1751 dim.height, stride, scanline,
1752 mParameters.getPreviewHalPixelFormat());
1753 mem = grallocMemory;
1754 }
1755 }
1756 break;
1757 case CAM_STREAM_TYPE_ANALYSIS:
1758 case CAM_STREAM_TYPE_SNAPSHOT:
1759 case CAM_STREAM_TYPE_RAW:
1760 case CAM_STREAM_TYPE_METADATA:
1761 case CAM_STREAM_TYPE_OFFLINE_PROC:
1762 mem = new QCameraStreamMemory(mGetMemory,
1763 bCachedMem,
1764 (bPoolMem) ? &m_memoryPool : NULL,
1765 stream_type);
1766 break;
1767 case CAM_STREAM_TYPE_VIDEO:
1768 {
1769 property_get("persist.camera.mem.usecache", value, "0");
1770 if (atoi(value) == 0) {
1771 bCachedMem = QCAMERA_ION_USE_NOCACHE;
1772 }
1773 CDBG_HIGH("%s: vidoe buf using cached memory = %d", __func__, bCachedMem);
1774 mem = new QCameraVideoMemory(mGetMemory, bCachedMem);
1775 }
1776 break;
1777 case CAM_STREAM_TYPE_DEFAULT:
1778 case CAM_STREAM_TYPE_MAX:
1779 default:
1780 break;
1781 }
1782 if (!mem) {
1783 return NULL;
1784 }
1785
1786 if (bufferCnt > 0) {
1787 if (mParameters.isSecureMode() &&
1788 (stream_type == CAM_STREAM_TYPE_RAW) &&
1789 (mParameters.isRdiMode())) {
1790 ALOGD("%s: Allocating %d secure buffers of size %d ", __func__, bufferCnt, size);
1791 rc = mem->allocate(bufferCnt, size, SECURE);
1792 } else {
1793 rc = mem->allocate(bufferCnt, size, NON_SECURE);
1794 }
1795 if (rc < 0) {
1796 delete mem;
1797 return NULL;
1798 }
1799 bufferCnt = mem->getCnt();
1800 }
1801 return mem;
1802 }
1803
1804 /*===========================================================================
1805 * FUNCTION : allocateMoreStreamBuf
1806 *
1807 * DESCRIPTION: alocate more stream buffers from the memory object
1808 *
1809 * PARAMETERS :
1810 * @mem_obj : memory object ptr
1811 * @size : size of buffer
1812 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated.
1813 * output will be the number of total buffers
1814 *
1815 * RETURN : int32_t type of status
1816 * NO_ERROR -- success
1817 * none-zero failure code
1818 *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,size_t size,uint8_t & bufferCnt)1819 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
1820 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
1821 {
1822 int rc = NO_ERROR;
1823
1824 if (bufferCnt > 0) {
1825 rc = mem_obj->allocateMore(bufferCnt, size);
1826 bufferCnt = mem_obj->getCnt();
1827 }
1828 return rc;
1829 }
1830
1831 /*===========================================================================
1832 * FUNCTION : allocateMiscBuf
1833 *
1834 * DESCRIPTION: alocate miscellaneous buffer
1835 *
1836 * PARAMETERS :
1837 * @streamInfo : stream info
1838 *
1839 * RETURN : ptr to a memory obj that holds stream info buffer.
1840 * NULL if failed
1841 *==========================================================================*/
allocateMiscBuf(cam_stream_info_t * streamInfo)1842 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
1843 cam_stream_info_t *streamInfo)
1844 {
1845 int rc = NO_ERROR;
1846 uint8_t bufNum = 0;
1847 size_t bufSize = 0;
1848 QCameraHeapMemory *miscBuf = NULL;
1849 uint32_t feature_mask =
1850 streamInfo->reprocess_config.pp_feature_config.feature_mask;
1851
1852 switch (streamInfo->stream_type) {
1853 case CAM_STREAM_TYPE_OFFLINE_PROC:
1854 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
1855 bufNum = 1;
1856 bufSize = mParameters.getTPMaxMetaSize();
1857 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
1858 bufNum = 1;
1859 bufSize = mParameters.getRefocusMaxMetaSize();
1860 }
1861 break;
1862 default:
1863 break;
1864 }
1865
1866 if (bufNum && bufSize) {
1867 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1868
1869 if (!miscBuf) {
1870 ALOGE("%s: Unable to allocate miscBuf object", __func__);
1871 return NULL;
1872 }
1873
1874 rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE);
1875 if (rc < 0) {
1876 ALOGE("%s: Failed to allocate misc buffer memory", __func__);
1877 delete miscBuf;
1878 return NULL;
1879 }
1880 }
1881
1882 return miscBuf;
1883 }
1884
1885 /*===========================================================================
1886 * FUNCTION : allocateStreamInfoBuf
1887 *
1888 * DESCRIPTION: alocate stream info buffer
1889 *
1890 * PARAMETERS :
1891 * @stream_type : type of stream
1892 *
1893 * RETURN : ptr to a memory obj that holds stream info buffer.
1894 * NULL if failed
1895 *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type)1896 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
1897 cam_stream_type_t stream_type)
1898 {
1899 int rc = NO_ERROR;
1900 char value[PROPERTY_VALUE_MAX];
1901 bool raw_yuv = false;
1902
1903 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1904 if (!streamInfoBuf) {
1905 ALOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
1906 return NULL;
1907 }
1908
1909 rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE);
1910 if (rc < 0) {
1911 ALOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
1912 delete streamInfoBuf;
1913 return NULL;
1914 }
1915
1916 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
1917 memset(streamInfo, 0, sizeof(cam_stream_info_t));
1918 streamInfo->stream_type = stream_type;
1919 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
1920 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
1921 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
1922 streamInfo->num_bufs = getBufNumRequired(stream_type);
1923 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1924 streamInfo->is_secure = NON_SECURE;
1925 switch (stream_type) {
1926 case CAM_STREAM_TYPE_SNAPSHOT:
1927 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
1928 mLongshotEnabled) {
1929 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1930 } else {
1931 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1932 streamInfo->num_of_burst = (uint8_t)
1933 (mParameters.getNumOfSnapshots()
1934 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
1935 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
1936 + mParameters.getNumOfExtraBuffersForImageProc());
1937 }
1938 break;
1939 case CAM_STREAM_TYPE_RAW:
1940 property_get("persist.camera.raw_yuv", value, "0");
1941 raw_yuv = atoi(value) > 0 ? true : false;
1942 if ((mParameters.isZSLMode() || isRdiMode() || raw_yuv) &&
1943 !mParameters.getofflineRAW()) {
1944 CDBG_HIGH("RDI_DEBUG %s[%d]: CAM_STREAM_TYPE_RAW",
1945 __func__, __LINE__);
1946 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1947 } else {
1948 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1949 streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
1950 }
1951 if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
1952 streamInfo->is_secure = SECURE;
1953 } else {
1954 streamInfo->is_secure = NON_SECURE;
1955 }
1956 break;
1957 case CAM_STREAM_TYPE_POSTVIEW:
1958 if (mLongshotEnabled) {
1959 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1960 } else {
1961 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1962 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
1963 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
1964 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
1965 + mParameters.getNumOfExtraBuffersForImageProc());
1966 }
1967 break;
1968 case CAM_STREAM_TYPE_VIDEO:
1969 streamInfo->dis_enable = mParameters.isDISEnabled();
1970 if (mParameters.getBufBatchCount()) {
1971 //Update stream info structure with batch mode info
1972 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
1973 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
1974 streamInfo->user_buf_info.size =
1975 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
1976 cam_fps_range_t pFpsRange;
1977 mParameters.getHfrFps(pFpsRange);
1978 streamInfo->user_buf_info.frameInterval =
1979 (long)((1000/pFpsRange.video_max_fps) * 1000);
1980 CDBG_HIGH("%s: Video Batch Count = %d, interval = %d", __func__,
1981 streamInfo->user_buf_info.frame_buf_cnt,
1982 streamInfo->user_buf_info.frameInterval);
1983 }
1984 case CAM_STREAM_TYPE_PREVIEW:
1985 if (mParameters.getRecordingHintValue()) {
1986 const char* dis_param = mParameters.get(QCameraParameters::KEY_QC_DIS);
1987 bool disEnabled = (dis_param != NULL)
1988 && !strcmp(dis_param,QCameraParameters::VALUE_ENABLE);
1989 if(disEnabled) {
1990 streamInfo->is_type = mParameters.getISType();
1991 } else {
1992 streamInfo->is_type = IS_TYPE_NONE;
1993 }
1994 }
1995 if (mParameters.isSecureMode()) {
1996 streamInfo->is_secure = SECURE;
1997 }
1998 break;
1999 case CAM_STREAM_TYPE_ANALYSIS:
2000 streamInfo->noFrameExpected = 1;
2001 break;
2002 default:
2003 break;
2004 }
2005
2006 // Update feature mask
2007 mParameters.updatePpFeatureMask(stream_type);
2008
2009 // Get feature mask
2010 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
2011
2012 // Update pp config
2013 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
2014 int flipMode = mParameters.getFlipMode(stream_type);
2015 if (flipMode > 0) {
2016 streamInfo->pp_config.flip = (uint32_t)flipMode;
2017 }
2018 }
2019 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
2020 streamInfo->pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS);
2021 }
2022 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
2023 streamInfo->pp_config.effect = mParameters.getEffectValue();
2024 }
2025
2026 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
2027 streamInfo->pp_config.denoise2d.denoise_enable = 1;
2028 streamInfo->pp_config.denoise2d.process_plates =
2029 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
2030 }
2031
2032 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
2033 CAM_STREAM_TYPE_RAW == stream_type))) {
2034 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_CROP)
2035 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
2036 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SCALE)
2037 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
2038 }
2039
2040 CDBG_HIGH("%s: allocateStreamInfoBuf: stream type: %d, pp_mask: 0x%x",
2041 __func__, stream_type, streamInfo->pp_config.feature_mask);
2042
2043 return streamInfoBuf;
2044 }
2045
2046 /*===========================================================================
2047 * FUNCTION : allocateStreamUserBuf
2048 *
2049 * DESCRIPTION: allocate user ptr for stream buffers
2050 *
2051 * PARAMETERS :
2052 * @streamInfo : stream info structure
2053 *
2054 * RETURN : ptr to a memory obj that holds stream info buffer.
2055 * NULL if failed
2056
2057 *==========================================================================*/
allocateStreamUserBuf(cam_stream_info_t * streamInfo)2058 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
2059 cam_stream_info_t *streamInfo)
2060 {
2061 int rc = NO_ERROR;
2062 QCameraMemory *mem = NULL;
2063 int bufferCnt = 0;
2064 int size = 0;
2065
2066 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
2067 ALOGE("%s: Stream is not in BATCH mode. Invalid Stream", __func__);
2068 return NULL;
2069 }
2070
2071 // Allocate stream user buffer memory object
2072 switch (streamInfo->stream_type) {
2073 case CAM_STREAM_TYPE_VIDEO: {
2074 QCameraVideoMemory *video_mem = new QCameraVideoMemory(
2075 mGetMemory, FALSE, CAM_STREAM_BUF_TYPE_USERPTR);
2076 video_mem->allocateMeta(streamInfo->num_bufs);
2077 mem = static_cast<QCameraMemory *>(video_mem);
2078 }
2079 break;
2080
2081 case CAM_STREAM_TYPE_PREVIEW:
2082 case CAM_STREAM_TYPE_POSTVIEW:
2083 case CAM_STREAM_TYPE_ANALYSIS:
2084 case CAM_STREAM_TYPE_SNAPSHOT:
2085 case CAM_STREAM_TYPE_RAW:
2086 case CAM_STREAM_TYPE_METADATA:
2087 case CAM_STREAM_TYPE_OFFLINE_PROC:
2088 case CAM_STREAM_TYPE_CALLBACK:
2089 ALOGE("%s: Stream type Not supported.for BATCH processing", __func__);
2090 break;
2091
2092 case CAM_STREAM_TYPE_DEFAULT:
2093 case CAM_STREAM_TYPE_MAX:
2094 default:
2095 break;
2096 }
2097 if (!mem) {
2098 ALOGE("%s: Failed to allocate mem", __func__);
2099 return NULL;
2100 }
2101
2102 /*Size of this buffer will be number of batch buffer */
2103 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
2104 CAM_PAD_TO_4K);
2105
2106 CDBG_HIGH("%s: Allocating BATCH Buffer count = %d", __func__, streamInfo->num_bufs);
2107
2108 if (size > 0) {
2109 // Allocating one buffer for all batch buffers
2110 rc = mem->allocate(1, size, NON_SECURE);
2111 if (rc < 0) {
2112 delete mem;
2113 return NULL;
2114 }
2115 }
2116 return mem;
2117 }
2118
2119
2120 /*===========================================================================
2121 * FUNCTION : setPreviewWindow
2122 *
2123 * DESCRIPTION: set preview window impl
2124 *
2125 * PARAMETERS :
2126 * @window : ptr to window ops table struct
2127 *
2128 * RETURN : int32_t type of status
2129 * NO_ERROR -- success
2130 * none-zero failure code
2131 *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)2132 int QCamera2HardwareInterface::setPreviewWindow(
2133 struct preview_stream_ops *window)
2134 {
2135 mPreviewWindow = window;
2136 return NO_ERROR;
2137 }
2138
2139 /*===========================================================================
2140 * FUNCTION : setCallBacks
2141 *
2142 * DESCRIPTION: set callbacks impl
2143 *
2144 * PARAMETERS :
2145 * @notify_cb : notify cb
2146 * @data_cb : data cb
2147 * @data_cb_timestamp : data cb with time stamp
2148 * @get_memory : request memory ops table
2149 * @user : user data ptr
2150 *
2151 * RETURN : int32_t type of status
2152 * NO_ERROR -- success
2153 * none-zero failure code
2154 *==========================================================================*/
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)2155 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
2156 camera_data_callback data_cb,
2157 camera_data_timestamp_callback data_cb_timestamp,
2158 camera_request_memory get_memory,
2159 void *user)
2160 {
2161 mNotifyCb = notify_cb;
2162 mDataCb = data_cb;
2163 mDataCbTimestamp = data_cb_timestamp;
2164 mGetMemory = get_memory;
2165 mCallbackCookie = user;
2166 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
2167 return NO_ERROR;
2168 }
2169
2170 /*===========================================================================
2171 * FUNCTION : enableMsgType
2172 *
2173 * DESCRIPTION: enable msg type impl
2174 *
2175 * PARAMETERS :
2176 * @msg_type : msg type mask to be enabled
2177 *
2178 * RETURN : int32_t type of status
2179 * NO_ERROR -- success
2180 * none-zero failure code
2181 *==========================================================================*/
enableMsgType(int32_t msg_type)2182 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
2183 {
2184 mMsgEnabled |= msg_type;
2185 return NO_ERROR;
2186 }
2187
2188 /*===========================================================================
2189 * FUNCTION : disableMsgType
2190 *
2191 * DESCRIPTION: disable msg type impl
2192 *
2193 * PARAMETERS :
2194 * @msg_type : msg type mask to be disabled
2195 *
2196 * RETURN : int32_t type of status
2197 * NO_ERROR -- success
2198 * none-zero failure code
2199 *==========================================================================*/
disableMsgType(int32_t msg_type)2200 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
2201 {
2202 mMsgEnabled &= ~msg_type;
2203 return NO_ERROR;
2204 }
2205
2206 /*===========================================================================
2207 * FUNCTION : msgTypeEnabled
2208 *
2209 * DESCRIPTION: impl to determine if certain msg_type is enabled
2210 *
2211 * PARAMETERS :
2212 * @msg_type : msg type mask
2213 *
2214 * RETURN : 0 -- not enabled
2215 * none 0 -- enabled
2216 *==========================================================================*/
msgTypeEnabled(int32_t msg_type)2217 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
2218 {
2219 return (mMsgEnabled & msg_type);
2220 }
2221
2222 /*===========================================================================
2223 * FUNCTION : msgTypeEnabledWithLock
2224 *
2225 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
2226 *
2227 * PARAMETERS :
2228 * @msg_type : msg type mask
2229 *
2230 * RETURN : 0 -- not enabled
2231 * none 0 -- enabled
2232 *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)2233 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
2234 {
2235 int enabled = 0;
2236 lockAPI();
2237 enabled = mMsgEnabled & msg_type;
2238 unlockAPI();
2239 return enabled;
2240 }
2241
2242 /*===========================================================================
2243 * FUNCTION : startPreview
2244 *
2245 * DESCRIPTION: start preview impl
2246 *
2247 * PARAMETERS : none
2248 *
2249 * RETURN : int32_t type of status
2250 * NO_ERROR -- success
2251 * none-zero failure code
2252 *==========================================================================*/
startPreview()2253 int QCamera2HardwareInterface::startPreview()
2254 {
2255 ATRACE_CALL();
2256 int32_t rc = NO_ERROR;
2257 CDBG_HIGH("%s: E", __func__);
2258 // start preview stream
2259 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
2260 rc = startChannel(QCAMERA_CH_TYPE_ZSL);
2261 } else {
2262 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
2263 /*
2264 CAF needs cancel auto focus to resume after snapshot.
2265 Focus should be locked till take picture is done.
2266 In Non-zsl case if focus mode is CAF then calling cancel auto focus
2267 to resume CAF.
2268 */
2269 cam_focus_mode_type focusMode = mParameters.getFocusMode();
2270 if (focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE)
2271 mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
2272 }
2273 updatePostPreviewParameters();
2274 CDBG_HIGH("%s: X", __func__);
2275 return rc;
2276 }
2277
updatePostPreviewParameters()2278 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
2279 // Enable OIS only in Camera mode and 4k2k camcoder mode
2280 int32_t rc = NO_ERROR;
2281 rc = mParameters.updateOisValue(1);
2282 return NO_ERROR;
2283 }
2284
2285 /*===========================================================================
2286 * FUNCTION : stopPreview
2287 *
2288 * DESCRIPTION: stop preview impl
2289 *
2290 * PARAMETERS : none
2291 *
2292 * RETURN : int32_t type of status
2293 * NO_ERROR -- success
2294 * none-zero failure code
2295 *==========================================================================*/
stopPreview()2296 int QCamera2HardwareInterface::stopPreview()
2297 {
2298 ATRACE_CALL();
2299 CDBG_HIGH("%s: E", __func__);
2300 // stop preview stream
2301 stopChannel(QCAMERA_CH_TYPE_ZSL);
2302 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
2303
2304 m_cbNotifier.flushPreviewNotifications();
2305 // delete all channels from preparePreview
2306 unpreparePreview();
2307 CDBG_HIGH("%s: X", __func__);
2308 return NO_ERROR;
2309 }
2310
2311 /*===========================================================================
2312 * FUNCTION : storeMetaDataInBuffers
2313 *
2314 * DESCRIPTION: enable store meta data in buffers for video frames impl
2315 *
2316 * PARAMETERS :
2317 * @enable : flag if need enable
2318 *
2319 * RETURN : int32_t type of status
2320 * NO_ERROR -- success
2321 * none-zero failure code
2322 *==========================================================================*/
storeMetaDataInBuffers(int enable)2323 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
2324 {
2325 mStoreMetaDataInFrame = enable;
2326 return NO_ERROR;
2327 }
2328
2329 /*===========================================================================
2330 * FUNCTION : startRecording
2331 *
2332 * DESCRIPTION: start recording impl
2333 *
2334 * PARAMETERS : none
2335 *
2336 * RETURN : int32_t type of status
2337 * NO_ERROR -- success
2338 * none-zero failure code
2339 *==========================================================================*/
startRecording()2340 int QCamera2HardwareInterface::startRecording()
2341 {
2342 int32_t rc = NO_ERROR;
2343 CDBG_HIGH("%s: E", __func__);
2344 if (mParameters.getRecordingHintValue() == false) {
2345 ALOGE("%s: start recording when hint is false, stop preview first", __func__);
2346 stopPreview();
2347
2348 // Set recording hint to TRUE
2349 mParameters.updateRecordingHintValue(TRUE);
2350 rc = preparePreview();
2351 if (rc == NO_ERROR) {
2352 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
2353 }
2354 }
2355
2356 if (rc == NO_ERROR) {
2357 rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
2358 }
2359
2360 if (rc == NO_ERROR) {
2361 // Set power Hint for video encoding
2362 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, 1);
2363 }
2364
2365 CDBG_HIGH("%s: X", __func__);
2366 return rc;
2367 }
2368
2369 /*===========================================================================
2370 * FUNCTION : stopRecording
2371 *
2372 * DESCRIPTION: stop recording impl
2373 *
2374 * PARAMETERS : none
2375 *
2376 * RETURN : int32_t type of status
2377 * NO_ERROR -- success
2378 * none-zero failure code
2379 *==========================================================================*/
stopRecording()2380 int QCamera2HardwareInterface::stopRecording()
2381 {
2382 CDBG_HIGH("%s: E", __func__);
2383 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
2384
2385 if (rc == NO_ERROR) {
2386 // Disable power Hint
2387 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, 0);
2388 }
2389 CDBG_HIGH("%s: X", __func__);
2390 return rc;
2391 }
2392
2393 /*===========================================================================
2394 * FUNCTION : releaseRecordingFrame
2395 *
2396 * DESCRIPTION: return video frame impl
2397 *
2398 * PARAMETERS :
2399 * @opaque : ptr to video frame to be returned
2400 *
2401 * RETURN : int32_t type of status
2402 * NO_ERROR -- success
2403 * none-zero failure code
2404 *==========================================================================*/
releaseRecordingFrame(const void * opaque)2405 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
2406 {
2407 int32_t rc = UNKNOWN_ERROR;
2408 QCameraVideoChannel *pChannel =
2409 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
2410 CDBG_HIGH("%s: opaque data = %p", __func__,opaque);
2411 if(pChannel != NULL) {
2412 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
2413 }
2414 return rc;
2415 }
2416
2417 /*===========================================================================
2418 * FUNCTION : autoFocus
2419 *
2420 * DESCRIPTION: start auto focus impl
2421 *
2422 * PARAMETERS : none
2423 *
2424 * RETURN : int32_t type of status
2425 * NO_ERROR -- success
2426 * none-zero failure code
2427 *==========================================================================*/
autoFocus()2428 int QCamera2HardwareInterface::autoFocus()
2429 {
2430 int rc = NO_ERROR;
2431 setCancelAutoFocus(false);
2432 cam_focus_mode_type focusMode = mParameters.getFocusMode();
2433
2434 switch (focusMode) {
2435 case CAM_FOCUS_MODE_AUTO:
2436 case CAM_FOCUS_MODE_MACRO:
2437 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
2438 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
2439 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
2440 break;
2441 case CAM_FOCUS_MODE_INFINITY:
2442 case CAM_FOCUS_MODE_FIXED:
2443 case CAM_FOCUS_MODE_EDOF:
2444 default:
2445 ALOGE("%s: No ops in focusMode (%d)", __func__, focusMode);
2446 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
2447 break;
2448 }
2449 return rc;
2450 }
2451
2452 /*===========================================================================
2453 * FUNCTION : cancelAutoFocus
2454 *
2455 * DESCRIPTION: cancel auto focus impl
2456 *
2457 * PARAMETERS : none
2458 *
2459 * RETURN : int32_t type of status
2460 * NO_ERROR -- success
2461 * none-zero failure code
2462 *==========================================================================*/
cancelAutoFocus()2463 int QCamera2HardwareInterface::cancelAutoFocus()
2464 {
2465 int rc = NO_ERROR;
2466 setCancelAutoFocus(true);
2467 cam_focus_mode_type focusMode = mParameters.getFocusMode();
2468
2469 switch (focusMode) {
2470 case CAM_FOCUS_MODE_AUTO:
2471 case CAM_FOCUS_MODE_MACRO:
2472 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
2473 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
2474 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
2475 break;
2476 case CAM_FOCUS_MODE_INFINITY:
2477 case CAM_FOCUS_MODE_FIXED:
2478 case CAM_FOCUS_MODE_EDOF:
2479 default:
2480 CDBG("%s: No ops in focusMode (%d)", __func__, focusMode);
2481 break;
2482 }
2483 return rc;
2484 }
2485
2486 /*===========================================================================
2487 * FUNCTION : processUFDumps
2488 *
2489 * DESCRIPTION: process UF jpeg dumps for refocus support
2490 *
2491 * PARAMETERS :
2492 * @evt : payload of jpeg event, including information about jpeg encoding
2493 * status, jpeg size and so on.
2494 *
2495 * RETURN : int32_t type of status
2496 * NO_ERROR -- success
2497 * none-zero failure code
2498 *
2499 * NOTE : none
2500 *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)2501 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
2502 {
2503 bool ret = true;
2504 if (mParameters.isUbiRefocus()) {
2505 int index = (int)getOutputImageCount();
2506 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
2507 char name[FILENAME_MAX];
2508
2509 camera_memory_t *jpeg_mem = NULL;
2510 omx_jpeg_ouput_buf_t *jpeg_out = NULL;
2511 size_t dataLen;
2512 uint8_t *dataPtr;
2513 if (!m_postprocessor.getJpegMemOpt()) {
2514 dataLen = evt->out_data.buf_filled_len;
2515 dataPtr = evt->out_data.buf_vaddr;
2516 } else {
2517 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
2518 if (!jpeg_out) {
2519 ALOGE("%s:%d] Null pointer detected", __func__, __LINE__);
2520 return false;
2521 }
2522 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
2523 if (!jpeg_mem) {
2524 ALOGE("%s:%d] Null pointer detected", __func__, __LINE__);
2525 return false;
2526 }
2527 dataPtr = (uint8_t *)jpeg_mem->data;
2528 dataLen = jpeg_mem->size;
2529 }
2530
2531 if (allFocusImage) {
2532 snprintf(name, sizeof(name), "AllFocusImage");
2533 index = -1;
2534 } else {
2535 snprintf(name, sizeof(name), "%d", 0);
2536 }
2537 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
2538 dataPtr, dataLen);
2539 CDBG("%s:%d] Dump the image %d %d allFocusImage %d", __func__, __LINE__,
2540 getOutputImageCount(), index, allFocusImage);
2541 setOutputImageCount(getOutputImageCount() + 1);
2542 if (!allFocusImage) {
2543 ret = false;
2544 }
2545 }
2546 return ret;
2547 }
2548
2549 /*===========================================================================
2550 * FUNCTION : unconfigureAdvancedCapture
2551 *
2552 * DESCRIPTION: unconfigure Advanced Capture.
2553 *
2554 * PARAMETERS : none
2555 *
2556 * RETURN : int32_t type of status
2557 * NO_ERROR -- success
2558 * none-zero failure code
2559 *==========================================================================*/
unconfigureAdvancedCapture()2560 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
2561 {
2562 int32_t rc = NO_ERROR;
2563
2564 if (mAdvancedCaptureConfigured) {
2565
2566 mAdvancedCaptureConfigured = false;
2567
2568 if(mIs3ALocked) {
2569 mParameters.set3ALock(QCameraParameters::VALUE_FALSE);
2570 mIs3ALocked = false;
2571 }
2572 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
2573 rc = mParameters.setToneMapMode(true, true);
2574 if (rc != NO_ERROR) {
2575 CDBG_HIGH("%s: Failed to enable tone map during HDR/AEBracketing", __func__);
2576 }
2577 mHDRBracketingEnabled = false;
2578 rc = mParameters.stopAEBracket();
2579 } else if (mParameters.isChromaFlashEnabled()) {
2580 rc = mParameters.resetFrameCapture(TRUE);
2581 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
2582 rc = configureAFBracketing(false);
2583 } else if (mParameters.isOptiZoomEnabled()) {
2584 rc = mParameters.setAndCommitZoom(mZoomLevel);
2585 } else if (mParameters.isStillMoreEnabled()) {
2586 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
2587 stillmore_config.burst_count = 0;
2588 mParameters.setStillMoreSettings(stillmore_config);
2589
2590 /* If SeeMore is running, it will handle re-enabling tone map */
2591 if (!mParameters.isSeeMoreEnabled()) {
2592 rc = mParameters.setToneMapMode(true, true);
2593 if (rc != NO_ERROR) {
2594 CDBG_HIGH("%s: Failed to enable tone map during StillMore", __func__);
2595 }
2596 }
2597
2598 /* Re-enable Tintless */
2599 mParameters.setTintless(true);
2600 } else {
2601 ALOGE("%s: No Advanced Capture feature enabled!! ", __func__);
2602 rc = BAD_VALUE;
2603 }
2604 }
2605
2606 return rc;
2607 }
2608
2609 /*===========================================================================
2610 * FUNCTION : configureAdvancedCapture
2611 *
2612 * DESCRIPTION: configure Advanced Capture.
2613 *
2614 * PARAMETERS : none
2615 *
2616 * RETURN : int32_t type of status
2617 * NO_ERROR -- success
2618 * none-zero failure code
2619 *==========================================================================*/
configureAdvancedCapture()2620 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
2621 {
2622 CDBG_HIGH("%s: E",__func__);
2623 int32_t rc = NO_ERROR;
2624
2625 setOutputImageCount(0);
2626 mInputCount = 0;
2627
2628 /* Temporarily stop display only if not in stillmore livesnapshot */
2629 if (!(mParameters.isStillMoreEnabled() &&
2630 mParameters.isSeeMoreEnabled())) {
2631 mParameters.setDisplayFrame(FALSE);
2632 }
2633
2634 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
2635 rc = configureAFBracketing();
2636 } else if (mParameters.isOptiZoomEnabled()) {
2637 rc = configureOptiZoom();
2638 } else if (mParameters.isChromaFlashEnabled()) {
2639 rc = mParameters.configFrameCapture(TRUE);
2640 } else if(mParameters.isHDREnabled()) {
2641 rc = configureHDRBracketing();
2642 if (mHDRBracketingEnabled) {
2643 rc = mParameters.setToneMapMode(false, true);
2644 if (rc != NO_ERROR) {
2645 CDBG_HIGH("%s: Failed to disable tone map during HDR", __func__);
2646 }
2647 }
2648 } else if (mParameters.isAEBracketEnabled()) {
2649 rc = mParameters.setToneMapMode(false, true);
2650 if (rc != NO_ERROR) {
2651 CDBG_HIGH("%s: Failed to disable tone map during AEBracketing", __func__);
2652 }
2653 rc = configureAEBracketing();
2654 } else if (mParameters.isStillMoreEnabled()) {
2655 rc = configureStillMore();
2656 } else {
2657 ALOGE("%s: No Advanced Capture feature enabled!! ", __func__);
2658 rc = BAD_VALUE;
2659 }
2660
2661 if (NO_ERROR == rc) {
2662 mAdvancedCaptureConfigured = true;
2663 } else {
2664 mAdvancedCaptureConfigured = false;
2665 }
2666
2667 CDBG_HIGH("%s: X",__func__);
2668 return rc;
2669 }
2670
2671 /*===========================================================================
2672 * FUNCTION : configureAFBracketing
2673 *
2674 * DESCRIPTION: configure AF Bracketing.
2675 *
2676 * PARAMETERS : none
2677 *
2678 * RETURN : int32_t type of status
2679 * NO_ERROR -- success
2680 * none-zero failure code
2681 *==========================================================================*/
configureAFBracketing(bool enable)2682 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
2683 {
2684 CDBG_HIGH("%s: E",__func__);
2685 int32_t rc = NO_ERROR;
2686 cam_af_bracketing_t *af_bracketing_need;
2687
2688 if (mParameters.isUbiRefocus()) {
2689 af_bracketing_need =
2690 &gCamCaps[mCameraId]->refocus_af_bracketing_need;
2691 } else {
2692 af_bracketing_need =
2693 &gCamCaps[mCameraId]->ubifocus_af_bracketing_need;
2694 }
2695
2696 //Enable AF Bracketing.
2697 cam_af_bracketing_t afBracket;
2698 memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
2699 afBracket.enable = enable;
2700 afBracket.burst_count = af_bracketing_need->burst_count;
2701
2702 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
2703 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
2704 CDBG_HIGH("%s: focus_step[%d] = %d", __func__, i, afBracket.focus_steps[i]);
2705 }
2706 //Send cmd to backend to set AF Bracketing for Ubi Focus.
2707 rc = mParameters.commitAFBracket(afBracket);
2708 if ( NO_ERROR != rc ) {
2709 ALOGE("%s: cannot configure AF bracketing", __func__);
2710 return rc;
2711 }
2712 if (enable) {
2713 mParameters.set3ALock(QCameraParameters::VALUE_TRUE);
2714 mIs3ALocked = true;
2715 }
2716 CDBG_HIGH("%s: X",__func__);
2717 return rc;
2718 }
2719
2720 /*===========================================================================
2721 * FUNCTION : configureHDRBracketing
2722 *
2723 * DESCRIPTION: configure HDR Bracketing.
2724 *
2725 * PARAMETERS : none
2726 *
2727 * RETURN : int32_t type of status
2728 * NO_ERROR -- success
2729 * none-zero failure code
2730 *==========================================================================*/
configureHDRBracketing()2731 int32_t QCamera2HardwareInterface::configureHDRBracketing()
2732 {
2733 CDBG_HIGH("%s: E",__func__);
2734 int32_t rc = NO_ERROR;
2735
2736 // 'values' should be in "idx1,idx2,idx3,..." format
2737 uint32_t hdrFrameCount = gCamCaps[mCameraId]->hdr_bracketing_setting.num_frames;
2738 CDBG_HIGH("%s : HDR values %d, %d frame count: %u",
2739 __func__,
2740 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[0],
2741 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[1],
2742 hdrFrameCount);
2743
2744 // Enable AE Bracketing for HDR
2745 cam_exp_bracketing_t aeBracket;
2746 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
2747 aeBracket.mode =
2748 gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.mode;
2749
2750 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
2751 mHDRBracketingEnabled = true;
2752 }
2753
2754 String8 tmp;
2755 for (uint32_t i = 0; i < hdrFrameCount; i++) {
2756 tmp.appendFormat("%d",
2757 (int8_t) gCamCaps[mCameraId]->hdr_bracketing_setting.exp_val.values[i]);
2758 tmp.append(",");
2759 }
2760 if (mParameters.isHDR1xFrameEnabled()
2761 && mParameters.isHDR1xExtraBufferNeeded()) {
2762 tmp.appendFormat("%d", 0);
2763 tmp.append(",");
2764 }
2765
2766 if( !tmp.isEmpty() &&
2767 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
2768 //Trim last comma
2769 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
2770 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
2771 }
2772
2773 CDBG_HIGH("%s : HDR config values %s",
2774 __func__,
2775 aeBracket.values);
2776 rc = mParameters.setHDRAEBracket(aeBracket);
2777 if ( NO_ERROR != rc ) {
2778 ALOGE("%s: cannot configure HDR bracketing", __func__);
2779 return rc;
2780 }
2781 CDBG_HIGH("%s: X",__func__);
2782 return rc;
2783 }
2784
2785 /*===========================================================================
2786 * FUNCTION : configureAEBracketing
2787 *
2788 * DESCRIPTION: configure AE Bracketing.
2789 *
2790 * PARAMETERS : none
2791 *
2792 * RETURN : int32_t type of status
2793 * NO_ERROR -- success
2794 * none-zero failure code
2795 *==========================================================================*/
configureAEBracketing()2796 int32_t QCamera2HardwareInterface::configureAEBracketing()
2797 {
2798 CDBG_HIGH("%s: E",__func__);
2799 int32_t rc = NO_ERROR;
2800
2801 rc = mParameters.setAEBracketing();
2802 if ( NO_ERROR != rc ) {
2803 ALOGE("%s: cannot configure AE bracketing", __func__);
2804 return rc;
2805 }
2806 CDBG_HIGH("%s: X",__func__);
2807 return rc;
2808 }
2809
2810 /*===========================================================================
2811 * FUNCTION : configureOptiZoom
2812 *
2813 * DESCRIPTION: configure Opti Zoom.
2814 *
2815 * PARAMETERS : none
2816 *
2817 * RETURN : int32_t type of status
2818 * NO_ERROR -- success
2819 * none-zero failure code
2820 *==========================================================================*/
configureOptiZoom()2821 int32_t QCamera2HardwareInterface::configureOptiZoom()
2822 {
2823 int32_t rc = NO_ERROR;
2824
2825 //store current zoom level.
2826 mZoomLevel = mParameters.getParmZoomLevel();
2827
2828 //set zoom level to 1x;
2829 mParameters.setAndCommitZoom(0);
2830
2831 mParameters.set3ALock(QCameraParameters::VALUE_TRUE);
2832 mIs3ALocked = true;
2833
2834 return rc;
2835 }
2836
2837 /*===========================================================================
2838 * FUNCTION : configureStillMore
2839 *
2840 * DESCRIPTION: configure StillMore.
2841 *
2842 * PARAMETERS : none
2843 *
2844 * RETURN : int32_t type of status
2845 * NO_ERROR -- success
2846 * none-zero failure code
2847 *==========================================================================*/
configureStillMore()2848 int32_t QCamera2HardwareInterface::configureStillMore()
2849 {
2850 int32_t rc = NO_ERROR;
2851 uint8_t burst_cnt = 0;
2852 cam_still_more_t stillmore_config;
2853 cam_still_more_t stillmore_cap;
2854
2855 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
2856 if (!mParameters.isSeeMoreEnabled()) {
2857 rc = mParameters.setToneMapMode(false, true);
2858 if (rc != NO_ERROR) {
2859 CDBG_HIGH("%s: Failed to disable tone map during StillMore", __func__);
2860 }
2861 }
2862
2863 /* Lock 3A */
2864 mParameters.set3ALock(QCameraParameters::VALUE_TRUE);
2865 mIs3ALocked = true;
2866
2867 /* Disable Tintless */
2868 mParameters.setTintless(false);
2869
2870 /* Configure burst count based on user input */
2871 char prop[PROPERTY_VALUE_MAX];
2872 property_get("persist.camera.imglib.stillmore", prop, "0");
2873 burst_cnt = (uint32_t)atoi(prop);
2874
2875 /* In the case of liveshot, burst should be 1 */
2876 if (mParameters.isSeeMoreEnabled()) {
2877 burst_cnt = 1;
2878 }
2879
2880 /* Validate burst count */
2881 stillmore_cap = mParameters.getStillMoreCapability();
2882 if ((burst_cnt < stillmore_cap.min_burst_count) ||
2883 (burst_cnt > stillmore_cap.max_burst_count)) {
2884 burst_cnt = stillmore_cap.max_burst_count;
2885 }
2886
2887 memset(&stillmore_config, 0, sizeof(cam_still_more_t));
2888 stillmore_config.burst_count = burst_cnt;
2889 mParameters.setStillMoreSettings(stillmore_config);
2890
2891 CDBG_HIGH("%s: Stillmore burst %d", __func__, burst_cnt);
2892
2893 return rc;
2894 }
2895
2896 /*===========================================================================
2897 * FUNCTION : stopAdvancedCapture
2898 *
2899 * DESCRIPTION: stops advanced capture based on capture type
2900 *
2901 * PARAMETERS :
2902 * @pChannel : channel.
2903 *
2904 * RETURN : int32_t type of status
2905 * NO_ERROR -- success
2906 * none-zero failure code
2907 *==========================================================================*/
stopAdvancedCapture(QCameraPicChannel * pChannel)2908 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
2909 QCameraPicChannel *pChannel)
2910 {
2911 CDBG_HIGH("%s: stop bracketig",__func__);
2912 int32_t rc = NO_ERROR;
2913
2914 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
2915 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
2916 } else if (mParameters.isChromaFlashEnabled()) {
2917 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
2918 } else if(mParameters.isHDREnabled()
2919 || mParameters.isAEBracketEnabled()) {
2920 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
2921 } else if (mParameters.isOptiZoomEnabled()) {
2922 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
2923 } else if (mParameters.isStillMoreEnabled()) {
2924 CDBG_HIGH("%s: stopAdvancedCapture not needed for StillMore", __func__);
2925 } else {
2926 ALOGE("%s: No Advanced Capture feature enabled!",__func__);
2927 rc = BAD_VALUE;
2928 }
2929 return rc;
2930 }
2931
2932 /*===========================================================================
2933 * FUNCTION : startAdvancedCapture
2934 *
2935 * DESCRIPTION: starts advanced capture based on capture type
2936 *
2937 * PARAMETERS :
2938 * @pChannel : channel.
2939 *
2940 * RETURN : int32_t type of status
2941 * NO_ERROR -- success
2942 * none-zero failure code
2943 *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)2944 int32_t QCamera2HardwareInterface::startAdvancedCapture(
2945 QCameraPicChannel *pChannel)
2946 {
2947 CDBG_HIGH("%s: Start bracketing",__func__);
2948 int32_t rc = NO_ERROR;
2949
2950 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
2951 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
2952 } else if (mParameters.isOptiZoomEnabled()) {
2953 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
2954 } else if (mParameters.isStillMoreEnabled()) {
2955 CDBG_HIGH("%s: startAdvancedCapture not needed for StillMore", __func__);
2956 } else if (mParameters.isHDREnabled()
2957 || mParameters.isAEBracketEnabled()) {
2958 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
2959 } else if (mParameters.isChromaFlashEnabled()) {
2960 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
2961 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
2962 } else {
2963 ALOGE("%s: No Advanced Capture feature enabled!",__func__);
2964 rc = BAD_VALUE;
2965 }
2966 return rc;
2967 }
2968
2969 /*===========================================================================
2970 * FUNCTION : takePicture
2971 *
2972 * DESCRIPTION: take picture impl
2973 *
2974 * PARAMETERS : none
2975 *
2976 * RETURN : int32_t type of status
2977 * NO_ERROR -- success
2978 * none-zero failure code
2979 *==========================================================================*/
takePicture()2980 int QCamera2HardwareInterface::takePicture()
2981 {
2982 int rc = NO_ERROR;
2983
2984 // Get total number for snapshots (retro + regular)
2985 uint8_t numSnapshots = mParameters.getNumOfSnapshots();
2986 // Get number of retro-active snapshots
2987 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
2988 CDBG_HIGH("%s: E", __func__);
2989
2990 //Set rotation value from user settings as Jpeg rotation
2991 //to configure back-end modules.
2992 mParameters.setJpegRotation(mParameters.getRotation());
2993
2994 // Check if retro-active snapshots are not enabled
2995 if (!isRetroPicture() || !mParameters.isZSLMode()) {
2996 numRetroSnapshots = 0;
2997 CDBG_HIGH("%s: [ZSL Retro] Reset retro snaphot count to zero", __func__);
2998 }
2999 if (mParameters.isUbiFocusEnabled() ||
3000 mParameters.isUbiRefocus() ||
3001 mParameters.isOptiZoomEnabled() ||
3002 mParameters.isHDREnabled() ||
3003 mParameters.isChromaFlashEnabled() ||
3004 mParameters.isAEBracketEnabled() ||
3005 mParameters.isStillMoreEnabled()) {
3006 rc = configureAdvancedCapture();
3007 if (rc == NO_ERROR) {
3008 numSnapshots = mParameters.getBurstCountForAdvancedCapture();
3009 }
3010 }
3011 CDBG_HIGH("%s: [ZSL Retro] numSnapshots = %d, numRetroSnapshots = %d",
3012 __func__, numSnapshots, numRetroSnapshots);
3013
3014 if (mParameters.isZSLMode()) {
3015 QCameraPicChannel *pZSLChannel =
3016 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
3017 if (NULL != pZSLChannel) {
3018
3019 rc = configureOnlineRotation(*pZSLChannel);
3020 if (rc != NO_ERROR) {
3021 ALOGE("%s: online rotation failed", __func__);
3022 return rc;
3023 }
3024
3025 // start postprocessor
3026 DefferWorkArgs args;
3027 memset(&args, 0, sizeof(DefferWorkArgs));
3028
3029 args.pprocArgs = pZSLChannel;
3030 mReprocJob = queueDefferedWork(CMD_DEFF_PPROC_START,
3031 args);
3032
3033 if (mParameters.isUbiFocusEnabled() ||
3034 mParameters.isUbiRefocus() ||
3035 mParameters.isOptiZoomEnabled() ||
3036 mParameters.isHDREnabled() ||
3037 mParameters.isChromaFlashEnabled() ||
3038 mParameters.isAEBracketEnabled() ||
3039 mParameters.isStillMoreEnabled()) {
3040 rc = startAdvancedCapture(pZSLChannel);
3041 if (rc != NO_ERROR) {
3042 ALOGE("%s: cannot start zsl advanced capture", __func__);
3043 return rc;
3044 }
3045 }
3046 if (mLongshotEnabled && mPrepSnapRun) {
3047 mCameraHandle->ops->start_zsl_snapshot(
3048 mCameraHandle->camera_handle,
3049 pZSLChannel->getMyHandle());
3050 }
3051 rc = pZSLChannel->takePicture(numSnapshots, numRetroSnapshots);
3052 if (rc != NO_ERROR) {
3053 ALOGE("%s: cannot take ZSL picture, stop pproc", __func__);
3054 waitDefferedWork(mReprocJob);
3055 m_postprocessor.stop();
3056 return rc;
3057 }
3058 } else {
3059 ALOGE("%s: ZSL channel is NULL", __func__);
3060 return UNKNOWN_ERROR;
3061 }
3062 } else {
3063
3064 // start snapshot
3065 if (mParameters.isJpegPictureFormat() ||
3066 mParameters.isNV16PictureFormat() ||
3067 mParameters.isNV21PictureFormat()) {
3068
3069 if (!isLongshotEnabled()) {
3070
3071 rc = addCaptureChannel();
3072
3073 // normal capture case
3074 // need to stop preview channel
3075 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3076 delChannel(QCAMERA_CH_TYPE_PREVIEW);
3077
3078 if (NO_ERROR == rc) {
3079 rc = declareSnapshotStreams();
3080 if (NO_ERROR != rc) {
3081 delChannel(QCAMERA_CH_TYPE_CAPTURE);
3082 return rc;
3083 }
3084 }
3085
3086 waitDefferedWork(mSnapshotJob);
3087 waitDefferedWork(mMetadataJob);
3088 waitDefferedWork(mRawdataJob);
3089
3090 {
3091 DefferWorkArgs args;
3092 DefferAllocBuffArgs allocArgs;
3093
3094 memset(&args, 0, sizeof(DefferWorkArgs));
3095 memset(&allocArgs, 0, sizeof(DefferAllocBuffArgs));
3096
3097 allocArgs.ch = m_channels[QCAMERA_CH_TYPE_CAPTURE];
3098 allocArgs.type = CAM_STREAM_TYPE_POSTVIEW;
3099 args.allocArgs = allocArgs;
3100
3101 mPostviewJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF,
3102 args);
3103
3104 if (mPostviewJob == -1) {
3105 rc = UNKNOWN_ERROR;
3106 }
3107 }
3108
3109 waitDefferedWork(mPostviewJob);
3110 } else {
3111 // normal capture case
3112 // need to stop preview channel
3113
3114 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3115 delChannel(QCAMERA_CH_TYPE_PREVIEW);
3116
3117 rc = declareSnapshotStreams();
3118 if (NO_ERROR != rc) {
3119 return rc;
3120 }
3121
3122 rc = addCaptureChannel();
3123 }
3124
3125 if ((rc == NO_ERROR) &&
3126 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
3127
3128 // configure capture channel
3129 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->config();
3130 if (rc != NO_ERROR) {
3131 ALOGE("%s: cannot configure capture channel", __func__);
3132 delChannel(QCAMERA_CH_TYPE_CAPTURE);
3133 return rc;
3134 }
3135
3136 if (!mParameters.getofflineRAW()) {
3137 rc = configureOnlineRotation(
3138 *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
3139 if (rc != NO_ERROR) {
3140 ALOGE("%s: online rotation failed", __func__);
3141 delChannel(QCAMERA_CH_TYPE_CAPTURE);
3142 return rc;
3143 }
3144 }
3145
3146 DefferWorkArgs args;
3147 memset(&args, 0, sizeof(DefferWorkArgs));
3148
3149 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
3150 mReprocJob = queueDefferedWork(CMD_DEFF_PPROC_START,
3151 args);
3152
3153 // start catpure channel
3154 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
3155 if (rc != NO_ERROR) {
3156 ALOGE("%s: cannot start capture channel", __func__);
3157 delChannel(QCAMERA_CH_TYPE_CAPTURE);
3158 return rc;
3159 }
3160
3161 QCameraPicChannel *pCapChannel =
3162 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
3163 if (NULL != pCapChannel) {
3164 if (mParameters.isUbiFocusEnabled() ||
3165 mParameters.isUbiRefocus() ||
3166 mParameters.isChromaFlashEnabled()) {
3167 rc = startAdvancedCapture(pCapChannel);
3168 if (rc != NO_ERROR) {
3169 ALOGE("%s: cannot start advanced capture", __func__);
3170 return rc;
3171 }
3172 }
3173 }
3174 if ( mLongshotEnabled ) {
3175 rc = longShot();
3176 if (NO_ERROR != rc) {
3177 delChannel(QCAMERA_CH_TYPE_CAPTURE);
3178 return rc;
3179 }
3180 }
3181 } else {
3182 ALOGE("%s: cannot add capture channel", __func__);
3183 delChannel(QCAMERA_CH_TYPE_CAPTURE);
3184 return rc;
3185 }
3186 } else {
3187
3188 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3189 delChannel(QCAMERA_CH_TYPE_PREVIEW);
3190
3191 rc = mParameters.updateRAW(gCamCaps[mCameraId]->raw_dim[0]);
3192 if (NO_ERROR != rc) {
3193 ALOGE("%s: Raw dimension update failed %d", __func__, rc);
3194 return rc;
3195 }
3196
3197 rc = declareSnapshotStreams();
3198 if (NO_ERROR != rc) {
3199 ALOGE("%s: RAW stream info configuration failed %d",
3200 __func__,
3201 rc);
3202 return rc;
3203 }
3204
3205 rc = addRawChannel();
3206 if (rc == NO_ERROR) {
3207 // start postprocessor
3208 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
3209 if (rc != NO_ERROR) {
3210 ALOGE("%s: cannot start postprocessor", __func__);
3211 delChannel(QCAMERA_CH_TYPE_RAW);
3212 return rc;
3213 }
3214
3215 rc = startChannel(QCAMERA_CH_TYPE_RAW);
3216 if (rc != NO_ERROR) {
3217 ALOGE("%s: cannot start raw channel", __func__);
3218 m_postprocessor.stop();
3219 delChannel(QCAMERA_CH_TYPE_RAW);
3220 return rc;
3221 }
3222 } else {
3223 ALOGE("%s: cannot add raw channel", __func__);
3224 return rc;
3225 }
3226 }
3227 }
3228 CDBG_HIGH("%s: X", __func__);
3229 return rc;
3230 }
3231
3232 /*===========================================================================
3233 * FUNCTION : configureOnlineRotation
3234 *
3235 * DESCRIPTION: Configure backend with expected rotation for snapshot stream
3236 *
3237 * PARAMETERS :
3238 * @ch : Channel containing a snapshot stream
3239 *
3240 * RETURN : int32_t type of status
3241 * NO_ERROR -- success
3242 * none-zero failure code
3243 *==========================================================================*/
configureOnlineRotation(QCameraChannel & ch)3244 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
3245 {
3246 int rc = NO_ERROR;
3247 uint32_t streamId = 0;
3248 QCameraStream *pStream = NULL;
3249
3250 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
3251 QCameraStream *stream = ch.getStreamByIndex(i);
3252 if ((NULL != stream) &&
3253 (CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())) {
3254 pStream = stream;
3255 break;
3256 }
3257 }
3258
3259 if (NULL == pStream) {
3260 ALOGE("%s: No snapshot stream found!", __func__);
3261 return BAD_VALUE;
3262 }
3263
3264 streamId = pStream->getMyServerID();
3265 // Update online rotation configuration
3266 pthread_mutex_lock(&m_parm_lock);
3267 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
3268 mParameters.getDeviceRotation());
3269 if (rc != NO_ERROR) {
3270 ALOGE("%s: addOnlineRotation failed %d", __func__, rc);
3271 pthread_mutex_unlock(&m_parm_lock);
3272 return rc;
3273 }
3274 pthread_mutex_unlock(&m_parm_lock);
3275
3276 return rc;
3277 }
3278
3279 /*===========================================================================
3280 * FUNCTION : declareSnapshotStreams
3281 *
3282 * DESCRIPTION: Configure backend with expected snapshot streams
3283 *
3284 * PARAMETERS : none
3285 *
3286 * RETURN : int32_t type of status
3287 * NO_ERROR -- success
3288 * none-zero failure code
3289 *==========================================================================*/
declareSnapshotStreams()3290 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
3291 {
3292 int rc = NO_ERROR;
3293
3294 // Update stream info configuration
3295 pthread_mutex_lock(&m_parm_lock);
3296 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
3297 if (rc != NO_ERROR) {
3298 ALOGE("%s: setStreamConfigure failed %d", __func__, rc);
3299 pthread_mutex_unlock(&m_parm_lock);
3300 return rc;
3301 }
3302 pthread_mutex_unlock(&m_parm_lock);
3303
3304 return rc;
3305 }
3306
3307 /*===========================================================================
3308 * FUNCTION : longShot
3309 *
3310 * DESCRIPTION: Queue one more ZSL frame
3311 * in the longshot pipe.
3312 *
3313 * PARAMETERS : none
3314 *
3315 * RETURN : int32_t type of status
3316 * NO_ERROR -- success
3317 * none-zero failure code
3318 *==========================================================================*/
longShot()3319 int32_t QCamera2HardwareInterface::longShot()
3320 {
3321 int32_t rc = NO_ERROR;
3322 uint8_t numSnapshots = mParameters.getNumOfSnapshots();
3323 QCameraPicChannel *pChannel = NULL;
3324
3325 if (mParameters.isZSLMode()) {
3326 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
3327 } else {
3328 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
3329 }
3330
3331 if (NULL != pChannel) {
3332 rc = pChannel->takePicture(numSnapshots, 0);
3333 } else {
3334 ALOGE(" %s : Capture channel not initialized!", __func__);
3335 rc = NO_INIT;
3336 goto end;
3337 }
3338
3339 end:
3340 return rc;
3341 }
3342
3343 /*===========================================================================
3344 * FUNCTION : stopCaptureChannel
3345 *
3346 * DESCRIPTION: Stops capture channel
3347 *
3348 * PARAMETERS :
3349 * @destroy : Set to true to stop and delete camera channel.
3350 * Set to false to only stop capture channel.
3351 *
3352 * RETURN : int32_t type of status
3353 * NO_ERROR -- success
3354 * none-zero failure code
3355 *==========================================================================*/
stopCaptureChannel(bool destroy)3356 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
3357 {
3358 int rc = NO_ERROR;
3359 if (mParameters.isJpegPictureFormat() ||
3360 mParameters.isNV16PictureFormat() ||
3361 mParameters.isNV21PictureFormat()) {
3362 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
3363 if (destroy && (NO_ERROR == rc)) {
3364 // Destroy camera channel but dont release context
3365 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
3366 }
3367 }
3368
3369 return rc;
3370 }
3371
3372 /*===========================================================================
3373 * FUNCTION : cancelPicture
3374 *
3375 * DESCRIPTION: cancel picture impl
3376 *
3377 * PARAMETERS : none
3378 *
3379 * RETURN : int32_t type of status
3380 * NO_ERROR -- success
3381 * none-zero failure code
3382 *==========================================================================*/
cancelPicture()3383 int QCamera2HardwareInterface::cancelPicture()
3384 {
3385 waitDefferedWork(mReprocJob);
3386
3387 //stop post processor
3388 m_postprocessor.stop();
3389
3390 unconfigureAdvancedCapture();
3391
3392 mParameters.setDisplayFrame(TRUE);
3393
3394 if (!mLongshotEnabled) {
3395 m_perfLock.lock_rel();
3396 }
3397
3398 if (mParameters.isZSLMode()) {
3399 QCameraPicChannel *pZSLChannel =
3400 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
3401 if (NULL != pZSLChannel) {
3402 stopAdvancedCapture(pZSLChannel);
3403 pZSLChannel->cancelPicture();
3404 }
3405 } else {
3406
3407 // normal capture case
3408 if (mParameters.isJpegPictureFormat() ||
3409 mParameters.isNV16PictureFormat() ||
3410 mParameters.isNV21PictureFormat()) {
3411 stopChannel(QCAMERA_CH_TYPE_CAPTURE);
3412 delChannel(QCAMERA_CH_TYPE_CAPTURE);
3413 } else {
3414 stopChannel(QCAMERA_CH_TYPE_RAW);
3415 delChannel(QCAMERA_CH_TYPE_RAW);
3416 }
3417 }
3418
3419 return NO_ERROR;
3420 }
3421
3422 /*===========================================================================
3423 * FUNCTION : captureDone
3424 *
3425 * DESCRIPTION: Function called when the capture is completed before encoding
3426 *
3427 * PARAMETERS : none
3428 *
3429 * RETURN : none
3430 *==========================================================================*/
captureDone()3431 void QCamera2HardwareInterface::captureDone()
3432 {
3433 qcamera_sm_internal_evt_payload_t *payload =
3434 (qcamera_sm_internal_evt_payload_t *)
3435 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
3436 if (NULL != payload) {
3437 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
3438 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
3439 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
3440 if (rc != NO_ERROR) {
3441 ALOGE("%s: processEvt ZSL capture done failed", __func__);
3442 free(payload);
3443 payload = NULL;
3444 }
3445 } else {
3446 ALOGE("%s: No memory for ZSL capture done event", __func__);
3447 }
3448 }
3449
3450 /*===========================================================================
3451 * FUNCTION : Live_Snapshot_thread
3452 *
3453 * DESCRIPTION: Seperate thread for taking live snapshot during recording
3454 *
3455 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
3456 *
3457 * RETURN : none
3458 *==========================================================================*/
Live_Snapshot_thread(void * data)3459 void* Live_Snapshot_thread (void* data)
3460 {
3461
3462 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
3463 if (!hw) {
3464 ALOGE("take_picture_thread: NULL camera device");
3465 return (void *)BAD_VALUE;
3466 }
3467 hw->takeLiveSnapshot_internal();
3468 return (void* )NULL;
3469 }
3470
3471 /*===========================================================================
3472 * FUNCTION : Int_Pic_thread
3473 *
3474 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
3475 *
3476 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
3477 *
3478 * RETURN : none
3479 *==========================================================================*/
Int_Pic_thread(void * data)3480 void* Int_Pic_thread (void* data)
3481 {
3482 int rc = NO_ERROR;
3483
3484 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
3485
3486 if (!hw) {
3487 ALOGE("take_picture_thread: NULL camera device");
3488 return (void *)BAD_VALUE;
3489 }
3490
3491 bool JpegMemOpt = false;
3492 char raw_format[PROPERTY_VALUE_MAX];
3493
3494 memset(raw_format, 0, sizeof(raw_format));
3495
3496 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
3497 if (rc == NO_ERROR) {
3498 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
3499 } else {
3500 //Snapshot attempt not successful, we need to do cleanup here
3501 hw->clearIntPendingEvents();
3502 }
3503
3504 return (void* )NULL;
3505 }
3506
3507 /*===========================================================================
3508 * FUNCTION : takeLiveSnapshot
3509 *
3510 * DESCRIPTION: take live snapshot during recording
3511 *
3512 * PARAMETERS : none
3513 *
3514 * RETURN : int32_t type of status
3515 * NO_ERROR -- success
3516 * none-zero failure code
3517 *==========================================================================*/
takeLiveSnapshot()3518 int QCamera2HardwareInterface::takeLiveSnapshot()
3519 {
3520 int rc = NO_ERROR;
3521 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
3522 return rc;
3523 }
3524
3525 /*===========================================================================
3526 * FUNCTION : takePictureInternal
3527 *
3528 * DESCRIPTION: take snapshot triggered by backend
3529 *
3530 * PARAMETERS : none
3531 *
3532 * RETURN : int32_t type of status
3533 * NO_ERROR -- success
3534 * none-zero failure code
3535 *==========================================================================*/
takePictureInternal()3536 int QCamera2HardwareInterface::takePictureInternal()
3537 {
3538 int rc = NO_ERROR;
3539 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
3540 return rc;
3541 }
3542
3543 /*===========================================================================
3544 * FUNCTION : checkIntPicPending
3545 *
3546 * DESCRIPTION: timed wait for jpeg completion event, and send
3547 * back completion event to backend
3548 *
3549 * PARAMETERS : none
3550 *
3551 * RETURN : none
3552 *==========================================================================*/
checkIntPicPending(bool JpegMemOpt,char * raw_format)3553 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
3554 {
3555 bool bSendToBackend = true;
3556 cam_int_evt_params_t params;
3557 int rc = NO_ERROR;
3558
3559 struct timespec ts;
3560 struct timeval tp;
3561 gettimeofday(&tp, NULL);
3562 ts.tv_sec = tp.tv_sec + 5;
3563 ts.tv_nsec = tp.tv_usec * 1000;
3564
3565 if (true == m_bIntJpegEvtPending ||
3566 (true == m_bIntRawEvtPending)) {
3567 //Waiting in HAL for snapshot taken notification
3568 pthread_mutex_lock(&m_int_lock);
3569 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
3570 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
3571 //Hit a timeout, or some spurious activity
3572 bSendToBackend = false;
3573 }
3574
3575 if (true == m_bIntJpegEvtPending) {
3576 params.event_type = 0;
3577 } else if (true == m_bIntRawEvtPending) {
3578 params.event_type = 1;
3579 }
3580 pthread_mutex_unlock(&m_int_lock);
3581
3582 if (true == m_bIntJpegEvtPending) {
3583 //Attempting to restart preview after taking JPEG snapshot
3584 lockAPI();
3585 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
3586 unlockAPI();
3587 m_postprocessor.setJpegMemOpt(JpegMemOpt);
3588 } else if (true == m_bIntRawEvtPending) {
3589 //Attempting to restart preview after taking RAW snapshot
3590 stopChannel(QCAMERA_CH_TYPE_RAW);
3591 delChannel(QCAMERA_CH_TYPE_RAW);
3592 //restoring the old raw format
3593 property_set("persist.camera.raw.format", raw_format);
3594 }
3595
3596 if (true == bSendToBackend) {
3597 //send event back to server with the file path
3598 params.dim = m_postprocessor.m_dst_dim;
3599 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
3600 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
3601 params.size = mBackendFileSize;
3602 pthread_mutex_lock(&m_parm_lock);
3603 rc = mParameters.setIntEvent(params);
3604 pthread_mutex_unlock(&m_parm_lock);
3605 }
3606
3607 clearIntPendingEvents();
3608 }
3609
3610 return;
3611 }
3612
3613 /*===========================================================================
3614 * FUNCTION : takeBackendPic_internal
3615 *
3616 * DESCRIPTION: take snapshot triggered by backend
3617 *
3618 * PARAMETERS : none
3619 *
3620 * RETURN : int32_t type of status
3621 * NO_ERROR -- success
3622 * none-zero failure code
3623 *==========================================================================*/
takeBackendPic_internal(bool * JpegMemOpt,char * raw_format)3624 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
3625 {
3626 int rc = NO_ERROR;
3627 qcamera_api_result_t apiResult;
3628
3629 lockAPI();
3630 //Set rotation value from user settings as Jpeg rotation
3631 //to configure back-end modules.
3632 mParameters.setJpegRotation(mParameters.getRotation());
3633
3634 setRetroPicture(0);
3635 /* Prepare snapshot in case LED needs to be flashed */
3636 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
3637 // Start Preparing for normal Frames
3638 CDBG_HIGH("%s: Start Prepare Snapshot", __func__);
3639 /* Prepare snapshot in case LED needs to be flashed */
3640 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
3641 if (rc == NO_ERROR) {
3642 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
3643 rc = apiResult.status;
3644 CDBG_HIGH("%s: Prep Snapshot done", __func__);
3645 }
3646 mPrepSnapRun = true;
3647 }
3648 unlockAPI();
3649
3650 if (true == m_bIntJpegEvtPending) {
3651 //Attempting to take JPEG snapshot
3652 *JpegMemOpt = m_postprocessor.getJpegMemOpt();
3653 m_postprocessor.setJpegMemOpt(false);
3654
3655 /* capture */
3656 lockAPI();
3657 CDBG_HIGH("%s: Capturing internal snapshot", __func__);
3658 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
3659 if (rc == NO_ERROR) {
3660 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
3661 rc = apiResult.status;
3662 }
3663 unlockAPI();
3664 } else if (true == m_bIntRawEvtPending) {
3665 //Attempting to take RAW snapshot
3666 (void)JpegMemOpt;
3667 stopPreview();
3668
3669 //getting the existing raw format type
3670 property_get("persist.camera.raw.format", raw_format, "16");
3671 //setting it to a default know value for this task
3672 property_set("persist.camera.raw.format", "18");
3673
3674 rc = addRawChannel();
3675 if (rc == NO_ERROR) {
3676 // start postprocessor
3677 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
3678 if (rc != NO_ERROR) {
3679 ALOGE("%s: cannot start postprocessor", __func__);
3680 delChannel(QCAMERA_CH_TYPE_RAW);
3681 return rc;
3682 }
3683
3684 rc = startChannel(QCAMERA_CH_TYPE_RAW);
3685 if (rc != NO_ERROR) {
3686 ALOGE("%s: cannot start raw channel", __func__);
3687 m_postprocessor.stop();
3688 delChannel(QCAMERA_CH_TYPE_RAW);
3689 return rc;
3690 }
3691 } else {
3692 ALOGE("%s: cannot add raw channel", __func__);
3693 return rc;
3694 }
3695 }
3696
3697 return rc;
3698 }
3699
3700 /*===========================================================================
3701 * FUNCTION : clearIntPendingEvents
3702 *
3703 * DESCRIPTION: clear internal pending events pertaining to backend
3704 * snapshot requests
3705 *
3706 * PARAMETERS : none
3707 *
3708 * RETURN : int32_t type of status
3709 * NO_ERROR -- success
3710 * none-zero failure code
3711 *==========================================================================*/
clearIntPendingEvents()3712 void QCamera2HardwareInterface::clearIntPendingEvents()
3713 {
3714 int rc = NO_ERROR;
3715
3716 if (true == m_bIntRawEvtPending) {
3717 preparePreview();
3718 startPreview();
3719 }
3720 if (true == m_bIntJpegEvtPending) {
3721 if (false == mParameters.isZSLMode()) {
3722 lockAPI();
3723 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
3724 unlockAPI();
3725 }
3726 }
3727
3728 pthread_mutex_lock(&m_int_lock);
3729 if (true == m_bIntJpegEvtPending) {
3730 m_bIntJpegEvtPending = false;
3731 } else if (true == m_bIntRawEvtPending) {
3732 m_bIntRawEvtPending = false;
3733 }
3734 pthread_mutex_unlock(&m_int_lock);
3735 return;
3736 }
3737
3738 /*===========================================================================
3739 * FUNCTION : takeLiveSnapshot_internal
3740 *
3741 * DESCRIPTION: take live snapshot during recording
3742 *
3743 * PARAMETERS : none
3744 *
3745 * RETURN : int32_t type of status
3746 * NO_ERROR -- success
3747 * none-zero failure code
3748 *==========================================================================*/
takeLiveSnapshot_internal()3749 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
3750 {
3751 int rc = NO_ERROR;
3752
3753 QCameraChannel *pChannel = NULL;
3754
3755 //Set rotation value from user settings as Jpeg rotation
3756 //to configure back-end modules.
3757 mParameters.setJpegRotation(mParameters.getRotation());
3758
3759 // Configure advanced capture
3760 if (mParameters.isUbiFocusEnabled() ||
3761 mParameters.isUbiRefocus() ||
3762 mParameters.isOptiZoomEnabled() ||
3763 mParameters.isHDREnabled() ||
3764 mParameters.isChromaFlashEnabled() ||
3765 mParameters.isAEBracketEnabled() ||
3766 mParameters.isStillMoreEnabled()) {
3767 rc = configureAdvancedCapture();
3768 if (rc != NO_ERROR) {
3769 CDBG_HIGH("%s: configureAdvancedCapture unsuccessful", __func__);
3770 }
3771 }
3772
3773 // start post processor
3774 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
3775 if (NO_ERROR != rc) {
3776 ALOGE("%s: Post-processor start failed %d", __func__, rc);
3777 goto end;
3778 }
3779
3780 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
3781 if (NULL == pChannel) {
3782 ALOGE("%s: Snapshot channel not initialized", __func__);
3783 rc = NO_INIT;
3784 goto end;
3785 }
3786 //Disable reprocess for 4K liveshot case
3787 if (!mParameters.is4k2kVideoResolution()) {
3788 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
3789 if (rc != NO_ERROR) {
3790 ALOGE("%s: online rotation failed", __func__);
3791 m_postprocessor.stop();
3792 return rc;
3793 }
3794 }
3795 // start snapshot channel
3796 if ((rc == NO_ERROR) && (NULL != pChannel)) {
3797 // Do not link metadata stream for 4K2k resolution
3798 // as CPP processing would be done on snapshot stream and not
3799 // reprocess stream
3800 if (!mParameters.is4k2kVideoResolution()) {
3801 // Find and try to link a metadata stream from preview channel
3802 QCameraChannel *pMetaChannel = NULL;
3803 QCameraStream *pMetaStream = NULL;
3804
3805 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
3806 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3807 uint32_t streamNum = pMetaChannel->getNumOfStreams();
3808 QCameraStream *pStream = NULL;
3809 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
3810 pStream = pMetaChannel->getStreamByIndex(i);
3811 if ((NULL != pStream) &&
3812 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
3813 pMetaStream = pStream;
3814 break;
3815 }
3816 }
3817 }
3818
3819 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
3820 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
3821 if (NO_ERROR != rc) {
3822 ALOGE("%s : Metadata stream link failed %d", __func__, rc);
3823 }
3824 }
3825 }
3826
3827 rc = pChannel->start();
3828 }
3829
3830 end:
3831 if (rc != NO_ERROR) {
3832 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
3833 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
3834 }
3835 return rc;
3836 }
3837
3838 /*===========================================================================
3839 * FUNCTION : cancelLiveSnapshot
3840 *
3841 * DESCRIPTION: cancel current live snapshot request
3842 *
3843 * PARAMETERS : none
3844 *
3845 * RETURN : int32_t type of status
3846 * NO_ERROR -- success
3847 * none-zero failure code
3848 *==========================================================================*/
cancelLiveSnapshot()3849 int QCamera2HardwareInterface::cancelLiveSnapshot()
3850 {
3851 int rc = NO_ERROR;
3852
3853 unconfigureAdvancedCapture();
3854 if (!mLongshotEnabled) {
3855 m_perfLock.lock_rel();
3856 }
3857
3858 if (mLiveSnapshotThread != 0) {
3859 pthread_join(mLiveSnapshotThread,NULL);
3860 mLiveSnapshotThread = 0;
3861 }
3862
3863 //stop post processor
3864 m_postprocessor.stop();
3865
3866 // stop snapshot channel
3867 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3868
3869 return rc;
3870 }
3871
3872 /*===========================================================================
3873 * FUNCTION : getParameters
3874 *
3875 * DESCRIPTION: get parameters impl
3876 *
3877 * PARAMETERS : none
3878 *
3879 * RETURN : a string containing parameter pairs
3880 *==========================================================================*/
getParameters()3881 char* QCamera2HardwareInterface::getParameters()
3882 {
3883 char* strParams = NULL;
3884 String8 str;
3885
3886 int cur_width, cur_height;
3887 pthread_mutex_lock(&m_parm_lock);
3888 //Need take care Scale picture size
3889 if(mParameters.m_reprocScaleParam.isScaleEnabled() &&
3890 mParameters.m_reprocScaleParam.isUnderScaling()){
3891 int scale_width, scale_height;
3892
3893 mParameters.m_reprocScaleParam.getPicSizeFromAPK(scale_width,scale_height);
3894 mParameters.getPictureSize(&cur_width, &cur_height);
3895
3896 String8 pic_size;
3897 char buffer[32];
3898 snprintf(buffer, sizeof(buffer), "%dx%d", scale_width, scale_height);
3899 pic_size.append(buffer);
3900 mParameters.set(CameraParameters::KEY_PICTURE_SIZE, pic_size);
3901 }
3902
3903 str = mParameters.flatten( );
3904 strParams = (char *)malloc(sizeof(char)*(str.length()+1));
3905 if(strParams != NULL){
3906 memset(strParams, 0, sizeof(char)*(str.length()+1));
3907 strlcpy(strParams, str.string(), str.length()+1);
3908 strParams[str.length()] = 0;
3909 }
3910
3911 if(mParameters.m_reprocScaleParam.isScaleEnabled() &&
3912 mParameters.m_reprocScaleParam.isUnderScaling()){
3913 //need set back picture size
3914 String8 pic_size;
3915 char buffer[32];
3916 snprintf(buffer, sizeof(buffer), "%dx%d", cur_width, cur_height);
3917 pic_size.append(buffer);
3918 mParameters.set(CameraParameters::KEY_PICTURE_SIZE, pic_size);
3919 }
3920 pthread_mutex_unlock(&m_parm_lock);
3921 return strParams;
3922 }
3923
3924 /*===========================================================================
3925 * FUNCTION : putParameters
3926 *
3927 * DESCRIPTION: put parameters string impl
3928 *
3929 * PARAMETERS :
3930 * @parms : parameters string to be released
3931 *
3932 * RETURN : int32_t type of status
3933 * NO_ERROR -- success
3934 * none-zero failure code
3935 *==========================================================================*/
putParameters(char * parms)3936 int QCamera2HardwareInterface::putParameters(char *parms)
3937 {
3938 free(parms);
3939 return NO_ERROR;
3940 }
3941
3942 /*===========================================================================
3943 * FUNCTION : sendCommand
3944 *
3945 * DESCRIPTION: send command impl
3946 *
3947 * PARAMETERS :
3948 * @command : command to be executed
3949 * @arg1 : optional argument 1
3950 * @arg2 : optional argument 2
3951 *
3952 * RETURN : int32_t type of status
3953 * NO_ERROR -- success
3954 * none-zero failure code
3955 *==========================================================================*/
sendCommand(int32_t command,int32_t & arg1,int32_t &)3956 int QCamera2HardwareInterface::sendCommand(int32_t command,
3957 int32_t &arg1, int32_t &/*arg2*/)
3958 {
3959 int rc = NO_ERROR;
3960
3961 switch (command) {
3962 #ifndef VANILLA_HAL
3963 case CAMERA_CMD_LONGSHOT_ON:
3964 m_perfLock.lock_acq();
3965 arg1 = 0;
3966 // Longshot can only be enabled when image capture
3967 // is not active.
3968 if ( !m_stateMachine.isCaptureRunning() ) {
3969 mLongshotEnabled = true;
3970 mParameters.setLongshotEnable(mLongshotEnabled);
3971
3972 // Due to recent buffer count optimizations
3973 // ZSL might run with considerably less buffers
3974 // when not in longshot mode. Preview needs to
3975 // restart in this case.
3976 if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
3977 QCameraChannel *pChannel = NULL;
3978 QCameraStream *pSnapStream = NULL;
3979 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
3980 if (NULL != pChannel) {
3981 QCameraStream *pStream = NULL;
3982 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
3983 pStream = pChannel->getStreamByIndex(i);
3984 if (pStream != NULL) {
3985 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
3986 pSnapStream = pStream;
3987 break;
3988 }
3989 }
3990 }
3991 if (NULL != pSnapStream) {
3992 uint8_t required = 0;
3993 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
3994 if (pSnapStream->getBufferCount() < required) {
3995 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
3996 }
3997 }
3998 }
3999 }
4000 //
4001 mPrepSnapRun = false;
4002 } else {
4003 rc = NO_INIT;
4004 }
4005 break;
4006 case CAMERA_CMD_LONGSHOT_OFF:
4007 m_perfLock.lock_rel();
4008 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
4009 cancelPicture();
4010 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
4011 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
4012 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
4013 mCameraHandle->ops->stop_zsl_snapshot(
4014 mCameraHandle->camera_handle,
4015 pZSLChannel->getMyHandle());
4016 }
4017 }
4018 mPrepSnapRun = false;
4019 mLongshotEnabled = false;
4020 mParameters.setLongshotEnable(mLongshotEnabled);
4021 break;
4022 case CAMERA_CMD_HISTOGRAM_ON:
4023 case CAMERA_CMD_HISTOGRAM_OFF:
4024 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
4025 break;
4026 #endif
4027 case CAMERA_CMD_START_FACE_DETECTION:
4028 case CAMERA_CMD_STOP_FACE_DETECTION:
4029 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
4030 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
4031 break;
4032 #ifndef VANILLA_HAL
4033 case CAMERA_CMD_HISTOGRAM_SEND_DATA:
4034 #endif
4035 default:
4036 rc = NO_ERROR;
4037 break;
4038 }
4039 return rc;
4040 }
4041
4042 /*===========================================================================
4043 * FUNCTION : registerFaceImage
4044 *
4045 * DESCRIPTION: register face image impl
4046 *
4047 * PARAMETERS :
4048 * @img_ptr : ptr to image buffer
4049 * @config : ptr to config struct about input image info
4050 * @faceID : [OUT] face ID to uniquely identifiy the registered face image
4051 *
4052 * RETURN : int32_t type of status
4053 * NO_ERROR -- success
4054 * none-zero failure code
4055 *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)4056 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
4057 cam_pp_offline_src_config_t *config,
4058 int32_t &faceID)
4059 {
4060 int rc = NO_ERROR;
4061 faceID = -1;
4062
4063 if (img_ptr == NULL || config == NULL) {
4064 ALOGE("%s: img_ptr or config is NULL", __func__);
4065 return BAD_VALUE;
4066 }
4067
4068 // allocate ion memory for source image
4069 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
4070 if (imgBuf == NULL) {
4071 ALOGE("%s: Unable to new heap memory obj for image buf", __func__);
4072 return NO_MEMORY;
4073 }
4074
4075 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE);
4076 if (rc < 0) {
4077 ALOGE("%s: Unable to allocate heap memory for image buf", __func__);
4078 delete imgBuf;
4079 return NO_MEMORY;
4080 }
4081
4082 void *pBufPtr = imgBuf->getPtr(0);
4083 if (pBufPtr == NULL) {
4084 ALOGE("%s: image buf is NULL", __func__);
4085 imgBuf->deallocate();
4086 delete imgBuf;
4087 return NO_MEMORY;
4088 }
4089 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
4090
4091 cam_pp_feature_config_t pp_feature;
4092 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
4093 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
4094 QCameraReprocessChannel *pChannel =
4095 addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
4096
4097 if (pChannel == NULL) {
4098 ALOGE("%s: fail to add offline reprocess channel", __func__);
4099 imgBuf->deallocate();
4100 delete imgBuf;
4101 return UNKNOWN_ERROR;
4102 }
4103
4104 rc = pChannel->start();
4105 if (rc != NO_ERROR) {
4106 ALOGE("%s: Cannot start reprocess channel", __func__);
4107 imgBuf->deallocate();
4108 delete imgBuf;
4109 delete pChannel;
4110 return rc;
4111 }
4112
4113 ssize_t bufSize = imgBuf->getSize(0);
4114 if (BAD_INDEX != bufSize) {
4115 rc = pChannel->doReprocess(imgBuf->getFd(0), (size_t)bufSize, faceID);
4116 } else {
4117 ALOGE("Failed to retrieve buffer size (bad index)");
4118 return UNKNOWN_ERROR;
4119 }
4120
4121 // done with register face image, free imgbuf and delete reprocess channel
4122 imgBuf->deallocate();
4123 delete imgBuf;
4124 imgBuf = NULL;
4125 pChannel->stop();
4126 delete pChannel;
4127 pChannel = NULL;
4128
4129 return rc;
4130 }
4131
4132 /*===========================================================================
4133 * FUNCTION : release
4134 *
4135 * DESCRIPTION: release camera resource impl
4136 *
4137 * PARAMETERS : none
4138 *
4139 * RETURN : int32_t type of status
4140 * NO_ERROR -- success
4141 * none-zero failure code
4142 *==========================================================================*/
release()4143 int QCamera2HardwareInterface::release()
4144 {
4145 // stop and delete all channels
4146 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
4147 if (m_channels[i] != NULL) {
4148 stopChannel((qcamera_ch_type_enum_t)i);
4149 delChannel((qcamera_ch_type_enum_t)i);
4150 }
4151 }
4152
4153 return NO_ERROR;
4154 }
4155
4156 /*===========================================================================
4157 * FUNCTION : dump
4158 *
4159 * DESCRIPTION: camera status dump impl
4160 *
4161 * PARAMETERS :
4162 * @fd : fd for the buffer to be dumped with camera status
4163 *
4164 * RETURN : int32_t type of status
4165 * NO_ERROR -- success
4166 * none-zero failure code
4167 *==========================================================================*/
dump(int fd)4168 int QCamera2HardwareInterface::dump(int fd)
4169 {
4170 dprintf(fd, "\n Camera HAL information Begin \n");
4171 dprintf(fd, "Camera ID: %d \n", mCameraId);
4172 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
4173 dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
4174 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
4175 dprintf(fd, "\n Camera HAL information End \n");
4176
4177 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
4178 debug level property */
4179 mParameters.updateDebugLevel();
4180 return NO_ERROR;
4181 }
4182
4183 /*===========================================================================
4184 * FUNCTION : processAPI
4185 *
4186 * DESCRIPTION: process API calls from upper layer
4187 *
4188 * PARAMETERS :
4189 * @api : API to be processed
4190 * @api_payload : ptr to API payload if any
4191 *
4192 * RETURN : int32_t type of status
4193 * NO_ERROR -- success
4194 * none-zero failure code
4195 *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)4196 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
4197 {
4198 int ret = DEAD_OBJECT;
4199
4200 if (m_smThreadActive) {
4201 ret = m_stateMachine.procAPI(api, api_payload);
4202 }
4203
4204 return ret;
4205 }
4206
4207 /*===========================================================================
4208 * FUNCTION : processEvt
4209 *
4210 * DESCRIPTION: process Evt from backend via mm-camera-interface
4211 *
4212 * PARAMETERS :
4213 * @evt : event type to be processed
4214 * @evt_payload : ptr to event payload if any
4215 *
4216 * RETURN : int32_t type of status
4217 * NO_ERROR -- success
4218 * none-zero failure code
4219 *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)4220 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
4221 {
4222 return m_stateMachine.procEvt(evt, evt_payload);
4223 }
4224
4225 /*===========================================================================
4226 * FUNCTION : processSyncEvt
4227 *
4228 * DESCRIPTION: process synchronous Evt from backend
4229 *
4230 * PARAMETERS :
4231 * @evt : event type to be processed
4232 * @evt_payload : ptr to event payload if any
4233 *
4234 * RETURN : int32_t type of status
4235 * NO_ERROR -- success
4236 * none-zero failure code
4237 *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)4238 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
4239 {
4240 int rc = NO_ERROR;
4241
4242 pthread_mutex_lock(&m_evtLock);
4243 rc = processEvt(evt, evt_payload);
4244 if (rc == NO_ERROR) {
4245 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
4246 while (m_evtResult.request_api != evt) {
4247 pthread_cond_wait(&m_evtCond, &m_evtLock);
4248 }
4249 rc = m_evtResult.status;
4250 }
4251 pthread_mutex_unlock(&m_evtLock);
4252
4253 return rc;
4254 }
4255
4256 /*===========================================================================
4257 * FUNCTION : evtHandle
4258 *
4259 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
4260 *
4261 * PARAMETERS :
4262 * @camera_handle : event type to be processed
4263 * @evt : ptr to event
4264 * @user_data : user data ptr
4265 *
4266 * RETURN : none
4267 *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)4268 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
4269 mm_camera_event_t *evt,
4270 void *user_data)
4271 {
4272 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
4273 if (obj && evt) {
4274 mm_camera_event_t *payload =
4275 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
4276 if (NULL != payload) {
4277 *payload = *evt;
4278 //peek into the event, if this is an eztune event from server,
4279 //then we don't need to post it to the SM Qs, we shud directly
4280 //spawn a thread and get the job done (jpeg or raw snapshot)
4281 switch (payload->server_event_type) {
4282 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
4283 //Received JPEG trigger from eztune
4284 if (false == obj->m_bIntJpegEvtPending) {
4285 pthread_mutex_lock(&obj->m_int_lock);
4286 obj->m_bIntJpegEvtPending = true;
4287 pthread_mutex_unlock(&obj->m_int_lock);
4288 obj->takePictureInternal();
4289 }
4290 free(payload);
4291 break;
4292 case CAM_EVENT_TYPE_INT_TAKE_RAW:
4293 //Received RAW trigger from eztune
4294 if (false == obj->m_bIntRawEvtPending) {
4295 pthread_mutex_lock(&obj->m_int_lock);
4296 obj->m_bIntRawEvtPending = true;
4297 pthread_mutex_unlock(&obj->m_int_lock);
4298 obj->takePictureInternal();
4299 }
4300 free(payload);
4301 break;
4302 case CAM_EVENT_TYPE_DAEMON_DIED:
4303 {
4304 Mutex::Autolock l(obj->mDeffLock);
4305 obj->mDeffCond.broadcast();
4306 CDBG_HIGH("%s: broadcast mDeffCond signal\n", __func__);
4307 }
4308 default:
4309 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
4310 break;
4311 }
4312 }
4313 } else {
4314 ALOGE("%s: NULL user_data", __func__);
4315 }
4316 }
4317
4318 /*===========================================================================
4319 * FUNCTION : jpegEvtHandle
4320 *
4321 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
4322 *
4323 * PARAMETERS :
4324 * @status : status of jpeg job
4325 * @client_hdl: jpeg client handle
4326 * @jobId : jpeg job Id
4327 * @p_ouput : ptr to jpeg output result struct
4328 * @userdata : user data ptr
4329 *
4330 * RETURN : none
4331 *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)4332 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
4333 uint32_t /*client_hdl*/,
4334 uint32_t jobId,
4335 mm_jpeg_output_t *p_output,
4336 void *userdata)
4337 {
4338 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
4339 if (obj) {
4340 qcamera_jpeg_evt_payload_t *payload =
4341 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
4342 if (NULL != payload) {
4343 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
4344 payload->status = status;
4345 payload->jobId = jobId;
4346 if (p_output != NULL) {
4347 payload->out_data = *p_output;
4348 }
4349 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
4350 }
4351 } else {
4352 ALOGE("%s: NULL user_data", __func__);
4353 }
4354 }
4355
4356 /*===========================================================================
4357 * FUNCTION : thermalEvtHandle
4358 *
4359 * DESCRIPTION: routine to handle thermal event notification
4360 *
4361 * PARAMETERS :
4362 * @level : thermal level
4363 * @userdata : userdata passed in during registration
4364 * @data : opaque data from thermal client
4365 *
4366 * RETURN : int32_t type of status
4367 * NO_ERROR -- success
4368 * none-zero failure code
4369 *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t * level,void * userdata,void * data)4370 int QCamera2HardwareInterface::thermalEvtHandle(
4371 qcamera_thermal_level_enum_t *level, void *userdata, void *data)
4372 {
4373 if (!mCameraOpened) {
4374 CDBG_HIGH("%s: Camera is not opened, no need to handle thermal evt", __func__);
4375 return NO_ERROR;
4376 }
4377
4378 // Make sure thermal events are logged
4379 CDBG_HIGH("%s: level = %d, userdata = %p, data = %p",
4380 __func__, *level, userdata, data);
4381 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
4382 // becomes an aync call. This also means we can only pass payload
4383 // by value, not by address.
4384 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
4385 }
4386
4387 /*===========================================================================
4388 * FUNCTION : sendEvtNotify
4389 *
4390 * DESCRIPTION: send event notify to notify thread
4391 *
4392 * PARAMETERS :
4393 * @msg_type: msg type to be sent
4394 * @ext1 : optional extension1
4395 * @ext2 : optional extension2
4396 *
4397 * RETURN : int32_t type of status
4398 * NO_ERROR -- success
4399 * none-zero failure code
4400 *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)4401 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
4402 int32_t ext1,
4403 int32_t ext2)
4404 {
4405 qcamera_callback_argm_t cbArg;
4406 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
4407 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
4408 cbArg.msg_type = msg_type;
4409 cbArg.ext1 = ext1;
4410 cbArg.ext2 = ext2;
4411 return m_cbNotifier.notifyCallback(cbArg);
4412 }
4413
4414 /*===========================================================================
4415 * FUNCTION : processAEInfo
4416 *
4417 * DESCRIPTION: process AE updates
4418 *
4419 * PARAMETERS :
4420 * @ae_params: current AE parameters
4421 *
4422 * RETURN : None
4423 *==========================================================================*/
processAEInfo(cam_3a_params_t & ae_params)4424 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
4425 {
4426 pthread_mutex_lock(&m_parm_lock);
4427 mParameters.updateAEInfo(ae_params);
4428 pthread_mutex_unlock(&m_parm_lock);
4429 return NO_ERROR;
4430 }
4431
4432 /*===========================================================================
4433 * FUNCTION : processFocusPositionInfo
4434 *
4435 * DESCRIPTION: process AF updates
4436 *
4437 * PARAMETERS :
4438 * @cur_pos_info: current lens position
4439 *
4440 * RETURN : None
4441 *==========================================================================*/
processFocusPositionInfo(cam_focus_pos_info_t & cur_pos_info)4442 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
4443 {
4444 pthread_mutex_lock(&m_parm_lock);
4445 mParameters.updateCurrentFocusPosition(cur_pos_info);
4446 pthread_mutex_unlock(&m_parm_lock);
4447 return NO_ERROR;
4448 }
4449
4450 /*===========================================================================
4451 * FUNCTION : processAutoFocusEvent
4452 *
4453 * DESCRIPTION: process auto focus event
4454 *
4455 * PARAMETERS :
4456 * @focus_data: struct containing auto focus result info
4457 *
4458 * RETURN : int32_t type of status
4459 * NO_ERROR -- success
4460 * none-zero failure code
4461 *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)4462 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
4463 {
4464 int32_t ret = NO_ERROR;
4465 CDBG_HIGH("%s: E",__func__);
4466
4467 m_currentFocusState = focus_data.focus_state;
4468
4469 cam_focus_mode_type focusMode = mParameters.getFocusMode();
4470 switch (focusMode) {
4471 case CAM_FOCUS_MODE_AUTO:
4472 case CAM_FOCUS_MODE_MACRO:
4473 if (getCancelAutoFocus()) {
4474 // auto focus has canceled, just ignore it
4475 break;
4476 }
4477 // If the HAL focus mode is AUTO and AF focus mode is INFINITY, send event to app
4478 if ((focusMode == CAM_FOCUS_MODE_AUTO) &&
4479 (focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
4480 (focus_data.focus_state == CAM_AF_INACTIVE)) {
4481 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
4482 break;
4483 }
4484 if (focus_data.focus_state == CAM_AF_SCANNING ||
4485 focus_data.focus_state == CAM_AF_INACTIVE) {
4486 // in the middle of focusing, just ignore it
4487 break;
4488 }
4489 // update focus distance
4490 mParameters.updateFocusDistances(&focus_data.focus_dist);
4491
4492 if ((CAM_AF_FOCUSED == focus_data.focus_state) &&
4493 mParameters.isZSLMode()) {
4494 QCameraPicChannel *pZSLChannel =
4495 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
4496 if (NULL != pZSLChannel) {
4497 //flush the zsl-buffer
4498 uint32_t flush_frame_idx = focus_data.focused_frame_idx;
4499 CDBG("%s, flush the zsl-buffer before frame = %u.", __func__, flush_frame_idx);
4500 pZSLChannel->flushSuperbuffer(flush_frame_idx);
4501 }
4502 }
4503
4504 ret = sendEvtNotify(CAMERA_MSG_FOCUS,
4505 (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
4506 0);
4507 break;
4508 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4509 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4510
4511 // If the HAL focus mode is AUTO and AF focus mode is INFINITY, send event to app
4512 if ((focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE) &&
4513 (focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
4514 (focus_data.focus_state == CAM_AF_INACTIVE)) {
4515 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
4516 break;
4517 }
4518
4519 if (focus_data.focus_state == CAM_AF_FOCUSED ||
4520 focus_data.focus_state == CAM_AF_NOT_FOCUSED) {
4521 // update focus distance
4522 mParameters.updateFocusDistances(&focus_data.focus_dist);
4523
4524 if ((focusMode == CAM_FOCUS_MODE_CONTINOUS_PICTURE) &&
4525 (CAM_AF_FOCUSED == focus_data.focus_state) &&
4526 mParameters.isZSLMode()) {
4527 QCameraPicChannel *pZSLChannel =
4528 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
4529 if (NULL != pZSLChannel) {
4530 //flush the zsl-buffer
4531 uint32_t flush_frame_idx = focus_data.focused_frame_idx;
4532 CDBG("%s, flush the zsl-buffer before frame = %u.", __func__, flush_frame_idx);
4533 pZSLChannel->flushSuperbuffer(flush_frame_idx);
4534 }
4535 }
4536
4537 ret = sendEvtNotify(CAMERA_MSG_FOCUS,
4538 (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
4539 0);
4540 }
4541 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
4542 (focus_data.focus_state == CAM_AF_SCANNING)? true : false,
4543 0);
4544 break;
4545 case CAM_FOCUS_MODE_INFINITY:
4546 case CAM_FOCUS_MODE_FIXED:
4547 case CAM_FOCUS_MODE_EDOF:
4548 default:
4549 CDBG_HIGH("%s: no ops for autofocus event in focusmode %d", __func__, focusMode);
4550 break;
4551 }
4552
4553 CDBG_HIGH("%s: X",__func__);
4554 return ret;
4555 }
4556
4557 /*===========================================================================
4558 * FUNCTION : processZoomEvent
4559 *
4560 * DESCRIPTION: process zoom event
4561 *
4562 * PARAMETERS :
4563 * @crop_info : crop info as a result of zoom operation
4564 *
4565 * RETURN : int32_t type of status
4566 * NO_ERROR -- success
4567 * none-zero failure code
4568 *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)4569 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
4570 {
4571 int32_t ret = NO_ERROR;
4572
4573 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
4574 if (m_channels[i] != NULL) {
4575 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
4576 }
4577 }
4578 return ret;
4579 }
4580
4581 /*===========================================================================
4582 * FUNCTION : processZSLCaptureDone
4583 *
4584 * DESCRIPTION: process ZSL capture done events
4585 *
4586 * PARAMETERS : None
4587 *
4588 * RETURN : int32_t type of status
4589 * NO_ERROR -- success
4590 * none-zero failure code
4591 *==========================================================================*/
processZSLCaptureDone()4592 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
4593 {
4594 int rc = NO_ERROR;
4595
4596 pthread_mutex_lock(&m_parm_lock);
4597 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
4598 rc = unconfigureAdvancedCapture();
4599 }
4600 pthread_mutex_unlock(&m_parm_lock);
4601
4602 return rc;
4603 }
4604
4605 /*===========================================================================
4606 * FUNCTION : processRetroAECUnlock
4607 *
4608 * DESCRIPTION: process retro burst AEC unlock events
4609 *
4610 * PARAMETERS : None
4611 *
4612 * RETURN : int32_t type of status
4613 * NO_ERROR -- success
4614 * none-zero failure code
4615 *==========================================================================*/
processRetroAECUnlock()4616 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
4617 {
4618 int rc = NO_ERROR;
4619
4620 CDBG_HIGH("%s : [ZSL Retro] LED assisted AF Release AEC Lock", __func__);
4621 pthread_mutex_lock(&m_parm_lock);
4622 rc = mParameters.setAecLock("false");
4623 if (NO_ERROR != rc) {
4624 ALOGE("%s: Error setting AEC lock", __func__);
4625 pthread_mutex_unlock(&m_parm_lock);
4626 return rc;
4627 }
4628
4629 rc = mParameters.commitParameters();
4630 if (NO_ERROR != rc) {
4631 ALOGE("%s: Error during camera parameter commit", __func__);
4632 } else {
4633 m_bLedAfAecLock = FALSE;
4634 }
4635
4636 pthread_mutex_unlock(&m_parm_lock);
4637
4638 return rc;
4639 }
4640
4641 /*===========================================================================
4642 * FUNCTION : processHDRData
4643 *
4644 * DESCRIPTION: process HDR scene events
4645 *
4646 * PARAMETERS :
4647 * @hdr_scene : HDR scene event data
4648 *
4649 * RETURN : int32_t type of status
4650 * NO_ERROR -- success
4651 * none-zero failure code
4652 *==========================================================================*/
processHDRData(cam_asd_hdr_scene_data_t hdr_scene)4653 int32_t QCamera2HardwareInterface::processHDRData(cam_asd_hdr_scene_data_t hdr_scene)
4654 {
4655 int rc = NO_ERROR;
4656
4657 #ifndef VANILLA_HAL
4658 if (hdr_scene.is_hdr_scene &&
4659 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
4660 mParameters.isAutoHDREnabled()) {
4661 m_HDRSceneEnabled = true;
4662 } else {
4663 m_HDRSceneEnabled = false;
4664 }
4665 pthread_mutex_lock(&m_parm_lock);
4666 mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
4667 pthread_mutex_unlock(&m_parm_lock);
4668
4669 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
4670
4671 size_t data_len = sizeof(int);
4672 size_t buffer_len = 1 *sizeof(int) //meta type
4673 + 1 *sizeof(int) //data len
4674 + 1 *sizeof(int); //data
4675 camera_memory_t *hdrBuffer = mGetMemory(-1,
4676 buffer_len,
4677 1,
4678 mCallbackCookie);
4679 if ( NULL == hdrBuffer ) {
4680 ALOGE("%s: Not enough memory for auto HDR data",
4681 __func__);
4682 return NO_MEMORY;
4683 }
4684
4685 int *pHDRData = (int *)hdrBuffer->data;
4686 if (pHDRData == NULL) {
4687 ALOGE("%s: memory data ptr is NULL", __func__);
4688 return UNKNOWN_ERROR;
4689 }
4690
4691 pHDRData[0] = CAMERA_META_DATA_HDR;
4692 pHDRData[1] = (int)data_len;
4693 pHDRData[2] = m_HDRSceneEnabled;
4694
4695 qcamera_callback_argm_t cbArg;
4696 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
4697 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
4698 cbArg.msg_type = CAMERA_MSG_META_DATA;
4699 cbArg.data = hdrBuffer;
4700 cbArg.user_data = hdrBuffer;
4701 cbArg.cookie = this;
4702 cbArg.release_cb = releaseCameraMemory;
4703 rc = m_cbNotifier.notifyCallback(cbArg);
4704 if (rc != NO_ERROR) {
4705 ALOGE("%s: fail sending auto HDR notification", __func__);
4706 hdrBuffer->release(hdrBuffer);
4707 }
4708 }
4709
4710 CDBG_HIGH("%s : hdr_scene_data: processHDRData: %d %f",
4711 __func__,
4712 hdr_scene.is_hdr_scene,
4713 hdr_scene.hdr_confidence);
4714
4715 #endif
4716 return rc;
4717 }
4718
4719 /*===========================================================================
4720 * FUNCTION : transAwbMetaToParams
4721 *
4722 * DESCRIPTION: translate awb params from metadata callback to QCameraParameters
4723 *
4724 * PARAMETERS :
4725 * @awb_params : awb params from metadata callback
4726 *
4727 * RETURN : int32_t type of status
4728 * NO_ERROR -- success
4729 * none-zero failure code
4730 *==========================================================================*/
transAwbMetaToParams(cam_awb_params_t & awb_params)4731 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
4732 {
4733 pthread_mutex_lock(&m_parm_lock);
4734 mParameters.updateAWBParams(awb_params);
4735 pthread_mutex_unlock(&m_parm_lock);
4736 return NO_ERROR;
4737 }
4738
4739 /*===========================================================================
4740 * FUNCTION : processPrepSnapshotDone
4741 *
4742 * DESCRIPTION: process prep snapshot done event
4743 *
4744 * PARAMETERS :
4745 * @prep_snapshot_state : state of prepare snapshot done. In other words,
4746 * i.e. whether need future frames for capture.
4747 *
4748 * RETURN : int32_t type of status
4749 * NO_ERROR -- success
4750 * none-zero failure code
4751 *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)4752 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
4753 cam_prep_snapshot_state_t prep_snapshot_state)
4754 {
4755 int32_t ret = NO_ERROR;
4756
4757 if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
4758 prep_snapshot_state == NEED_FUTURE_FRAME) {
4759 CDBG_HIGH("%s: already handled in mm-camera-intf, no ops here", __func__);
4760 if (isRetroPicture()) {
4761 mParameters.setAecLock("true");
4762 mParameters.commitParameters();
4763 m_bLedAfAecLock = TRUE;
4764 }
4765 }
4766 return ret;
4767 }
4768
4769 /*===========================================================================
4770 * FUNCTION : processASDUpdate
4771 *
4772 * DESCRIPTION: process ASD update event
4773 *
4774 * PARAMETERS :
4775 * @scene: selected scene mode
4776 *
4777 * RETURN : int32_t type of status
4778 * NO_ERROR -- success
4779 * none-zero failure code
4780 *==========================================================================*/
processASDUpdate(cam_auto_scene_t scene)4781 int32_t QCamera2HardwareInterface::processASDUpdate(cam_auto_scene_t scene)
4782 {
4783 //set ASD parameter
4784 mParameters.set(QCameraParameters::KEY_SELECTED_AUTO_SCENE, mParameters.getASDStateString(scene));
4785
4786 size_t data_len = sizeof(cam_auto_scene_t);
4787 size_t buffer_len = 1 *sizeof(int) //meta type
4788 + 1 *sizeof(int) //data len
4789 + data_len; //data
4790 camera_memory_t *asdBuffer = mGetMemory(-1,
4791 buffer_len,
4792 1,
4793 mCallbackCookie);
4794 if ( NULL == asdBuffer ) {
4795 ALOGE("%s: Not enough memory for histogram data", __func__);
4796 return NO_MEMORY;
4797 }
4798
4799 int *pASDData = (int *)asdBuffer->data;
4800 if (pASDData == NULL) {
4801 ALOGE("%s: memory data ptr is NULL", __func__);
4802 return UNKNOWN_ERROR;
4803 }
4804
4805 #ifndef VANILLA_HAL
4806 pASDData[0] = CAMERA_META_DATA_ASD;
4807 pASDData[1] = (int)data_len;
4808 pASDData[2] = scene;
4809
4810 qcamera_callback_argm_t cbArg;
4811 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
4812 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
4813 cbArg.msg_type = CAMERA_MSG_META_DATA;
4814 cbArg.data = asdBuffer;
4815 cbArg.user_data = asdBuffer;
4816 cbArg.cookie = this;
4817 cbArg.release_cb = releaseCameraMemory;
4818 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
4819 if (rc != NO_ERROR) {
4820 ALOGE("%s: fail sending notification", __func__);
4821 asdBuffer->release(asdBuffer);
4822 }
4823 #endif
4824 return NO_ERROR;
4825
4826 }
4827
4828 /*===========================================================================
4829 * FUNCTION : processJpegNotify
4830 *
4831 * DESCRIPTION: process jpeg event
4832 *
4833 * PARAMETERS :
4834 * @jpeg_evt: ptr to jpeg event payload
4835 *
4836 * RETURN : int32_t type of status
4837 * NO_ERROR -- success
4838 * none-zero failure code
4839 *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)4840 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
4841 {
4842 return m_postprocessor.processJpegEvt(jpeg_evt);
4843 }
4844
4845 /*===========================================================================
4846 * FUNCTION : lockAPI
4847 *
4848 * DESCRIPTION: lock to process API
4849 *
4850 * PARAMETERS : none
4851 *
4852 * RETURN : none
4853 *==========================================================================*/
lockAPI()4854 void QCamera2HardwareInterface::lockAPI()
4855 {
4856 pthread_mutex_lock(&m_lock);
4857 }
4858
4859 /*===========================================================================
4860 * FUNCTION : waitAPIResult
4861 *
4862 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
4863 * return only cerntain API event type arrives
4864 *
4865 * PARAMETERS :
4866 * @api_evt : API event type
4867 *
4868 * RETURN : none
4869 *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)4870 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
4871 qcamera_api_result_t *apiResult)
4872 {
4873 CDBG("%s: wait for API result of evt (%d)", __func__, api_evt);
4874 int resultReceived = 0;
4875 while (!resultReceived) {
4876 pthread_cond_wait(&m_cond, &m_lock);
4877 if (m_apiResultList != NULL) {
4878 api_result_list *apiResultList = m_apiResultList;
4879 api_result_list *apiResultListPrevious = m_apiResultList;
4880 while (apiResultList != NULL) {
4881 if (apiResultList->result.request_api == api_evt) {
4882 resultReceived = 1;
4883 *apiResult = apiResultList->result;
4884 apiResultListPrevious->next = apiResultList->next;
4885 if (apiResultList == m_apiResultList) {
4886 m_apiResultList = apiResultList->next;
4887 }
4888 free(apiResultList);
4889 break;
4890 }
4891 else {
4892 apiResultListPrevious = apiResultList;
4893 apiResultList = apiResultList->next;
4894 }
4895 }
4896 }
4897 }
4898 CDBG("%s: return (%d) from API result wait for evt (%d)",
4899 __func__, apiResult->status, api_evt);
4900 }
4901
4902
4903 /*===========================================================================
4904 * FUNCTION : unlockAPI
4905 *
4906 * DESCRIPTION: API processing is done, unlock
4907 *
4908 * PARAMETERS : none
4909 *
4910 * RETURN : none
4911 *==========================================================================*/
unlockAPI()4912 void QCamera2HardwareInterface::unlockAPI()
4913 {
4914 pthread_mutex_unlock(&m_lock);
4915 }
4916
4917 /*===========================================================================
4918 * FUNCTION : signalAPIResult
4919 *
4920 * DESCRIPTION: signal condition viarable that cerntain API event type arrives
4921 *
4922 * PARAMETERS :
4923 * @result : API result
4924 *
4925 * RETURN : none
4926 *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)4927 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
4928 {
4929
4930 pthread_mutex_lock(&m_lock);
4931 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
4932 if (apiResult == NULL) {
4933 ALOGE("%s: ERROR: malloc for api result failed", __func__);
4934 ALOGE("%s: ERROR: api thread will wait forever fot this lost result", __func__);
4935 goto malloc_failed;
4936 }
4937 apiResult->result = *result;
4938 apiResult->next = NULL;
4939 if (m_apiResultList == NULL) m_apiResultList = apiResult;
4940 else {
4941 api_result_list *apiResultList = m_apiResultList;
4942 while(apiResultList->next != NULL) apiResultList = apiResultList->next;
4943 apiResultList->next = apiResult;
4944 }
4945 malloc_failed:
4946 pthread_cond_broadcast(&m_cond);
4947 pthread_mutex_unlock(&m_lock);
4948 }
4949
4950 /*===========================================================================
4951 * FUNCTION : signalEvtResult
4952 *
4953 * DESCRIPTION: signal condition variable that certain event was processed
4954 *
4955 * PARAMETERS :
4956 * @result : Event result
4957 *
4958 * RETURN : none
4959 *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)4960 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
4961 {
4962 pthread_mutex_lock(&m_evtLock);
4963 m_evtResult = *result;
4964 pthread_cond_signal(&m_evtCond);
4965 pthread_mutex_unlock(&m_evtLock);
4966 }
4967
prepareRawStream(QCameraChannel * curChannel)4968 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
4969 {
4970 int32_t rc = NO_ERROR;
4971 cam_dimension_t str_dim,max_dim;
4972 QCameraChannel *pChannel;
4973
4974 max_dim.width = 0;
4975 max_dim.height = 0;
4976
4977 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
4978 if (m_channels[j] != NULL) {
4979 pChannel = m_channels[j];
4980 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
4981 QCameraStream *pStream = pChannel->getStreamByIndex(i);
4982 if (pStream != NULL) {
4983 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
4984 continue;
4985 }
4986 pStream->getFrameDimension(str_dim);
4987 if (str_dim.width > max_dim.width) {
4988 max_dim.width = str_dim.width;
4989 }
4990 if (str_dim.height > max_dim.height) {
4991 max_dim.height = str_dim.height;
4992 }
4993 }
4994 }
4995 }
4996 }
4997
4998 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
4999 QCameraStream *pStream = curChannel->getStreamByIndex(i);
5000 if (pStream != NULL) {
5001 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
5002 continue;
5003 }
5004 pStream->getFrameDimension(str_dim);
5005 if (str_dim.width > max_dim.width) {
5006 max_dim.width = str_dim.width;
5007 }
5008 if (str_dim.height > max_dim.height) {
5009 max_dim.height = str_dim.height;
5010 }
5011 }
5012 }
5013 rc = mParameters.updateRAW(max_dim);
5014 return rc;
5015 }
5016 /*===========================================================================
5017 * FUNCTION : addStreamToChannel
5018 *
5019 * DESCRIPTION: add a stream into a channel
5020 *
5021 * PARAMETERS :
5022 * @pChannel : ptr to channel obj
5023 * @streamType : type of stream to be added
5024 * @streamCB : callback of stream
5025 * @userData : user data ptr to callback
5026 *
5027 * RETURN : int32_t type of status
5028 * NO_ERROR -- success
5029 * none-zero failure code
5030 *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)5031 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
5032 cam_stream_type_t streamType,
5033 stream_cb_routine streamCB,
5034 void *userData)
5035 {
5036 int32_t rc = NO_ERROR;
5037
5038 if (streamType == CAM_STREAM_TYPE_RAW) {
5039 prepareRawStream(pChannel);
5040 }
5041 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
5042 if (pStreamInfo == NULL) {
5043 ALOGE("%s: no mem for stream info buf", __func__);
5044 return NO_MEMORY;
5045 }
5046 uint8_t minStreamBufNum = getBufNumRequired(streamType);
5047 bool bDynAllocBuf = false;
5048 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
5049 bDynAllocBuf = true;
5050 }
5051
5052 if ( ( streamType == CAM_STREAM_TYPE_SNAPSHOT ||
5053 streamType == CAM_STREAM_TYPE_POSTVIEW ||
5054 streamType == CAM_STREAM_TYPE_METADATA ||
5055 streamType == CAM_STREAM_TYPE_RAW) &&
5056 !isZSLMode() &&
5057 !isLongshotEnabled() &&
5058 !mParameters.getRecordingHintValue() &&
5059 !mParameters.isSecureMode()) {
5060 rc = pChannel->addStream(*this,
5061 pStreamInfo,
5062 NULL,
5063 minStreamBufNum,
5064 &gCamCaps[mCameraId]->padding_info,
5065 streamCB, userData,
5066 bDynAllocBuf,
5067 true);
5068
5069 // Queue buffer allocation for Snapshot and Metadata streams
5070 if ( !rc ) {
5071 DefferWorkArgs args;
5072 DefferAllocBuffArgs allocArgs;
5073
5074 memset(&args, 0, sizeof(DefferWorkArgs));
5075 memset(&allocArgs, 0, sizeof(DefferAllocBuffArgs));
5076 allocArgs.type = streamType;
5077 allocArgs.ch = pChannel;
5078 args.allocArgs = allocArgs;
5079
5080 if (streamType == CAM_STREAM_TYPE_SNAPSHOT) {
5081 mSnapshotJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF,
5082 args);
5083
5084 if ( mSnapshotJob == -1) {
5085 rc = UNKNOWN_ERROR;
5086 }
5087 } else if (streamType == CAM_STREAM_TYPE_METADATA) {
5088 mMetadataJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF,
5089 args);
5090
5091 if ( mMetadataJob == -1) {
5092 rc = UNKNOWN_ERROR;
5093 }
5094 } else if (streamType == CAM_STREAM_TYPE_RAW) {
5095 mRawdataJob = queueDefferedWork(CMD_DEFF_ALLOCATE_BUFF,
5096 args);
5097
5098 if ( mRawdataJob == -1) {
5099 rc = UNKNOWN_ERROR;
5100 }
5101 }
5102 }
5103 } else if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
5104 rc = pChannel->addStream(*this,
5105 pStreamInfo,
5106 NULL,
5107 minStreamBufNum,
5108 &gCamCaps[mCameraId]->analysis_padding_info,
5109 streamCB, userData,
5110 bDynAllocBuf,
5111 false);
5112 } else {
5113 rc = pChannel->addStream(*this,
5114 pStreamInfo,
5115 NULL,
5116 minStreamBufNum,
5117 &gCamCaps[mCameraId]->padding_info,
5118 streamCB, userData,
5119 bDynAllocBuf,
5120 false);
5121 }
5122
5123 if (rc != NO_ERROR) {
5124 ALOGE("%s: add stream type (%d) failed, ret = %d",
5125 __func__, streamType, rc);
5126 }
5127
5128 return rc;
5129 }
5130
5131 /*===========================================================================
5132 * FUNCTION : addPreviewChannel
5133 *
5134 * DESCRIPTION: add a preview channel that contains a preview stream
5135 *
5136 * PARAMETERS : none
5137 *
5138 * RETURN : int32_t type of status
5139 * NO_ERROR -- success
5140 * none-zero failure code
5141 *==========================================================================*/
addPreviewChannel()5142 int32_t QCamera2HardwareInterface::addPreviewChannel()
5143 {
5144 int32_t rc = NO_ERROR;
5145 QCameraChannel *pChannel = NULL;
5146
5147 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
5148 // if we had preview channel before, delete it first
5149 delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
5150 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
5151 }
5152
5153 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
5154 mCameraHandle->ops);
5155 if (NULL == pChannel) {
5156 ALOGE("%s: no mem for preview channel", __func__);
5157 return NO_MEMORY;
5158 }
5159
5160 // preview only channel, don't need bundle attr and cb
5161 rc = pChannel->init(NULL, NULL, NULL);
5162 if (rc != NO_ERROR) {
5163 ALOGE("%s: init preview channel failed, ret = %d", __func__, rc);
5164 return rc;
5165 }
5166
5167 // meta data stream always coexists with preview if applicable
5168 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
5169 metadata_stream_cb_routine, this);
5170 if (rc != NO_ERROR) {
5171 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
5172 return rc;
5173 }
5174
5175 if (mParameters.getRecordingHintValue() != true && !mParameters.isSecureMode()) {
5176 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
5177 NULL, this);
5178 if (rc != NO_ERROR) {
5179 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc);
5180 return rc;
5181 }
5182 }
5183
5184 if (isRdiMode()) {
5185 CDBG_HIGH("RDI_DEBUG %s[%d]: Add stream to channel", __func__, __LINE__);
5186 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
5187 rdi_mode_stream_cb_routine, this);
5188 } else {
5189 if (isNoDisplayMode()) {
5190 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
5191 nodisplay_preview_stream_cb_routine, this);
5192 } else {
5193 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
5194 preview_stream_cb_routine, this);
5195 }
5196 }
5197
5198 if (rc != NO_ERROR) {
5199 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
5200 delete pChannel;
5201 return rc;
5202 }
5203
5204 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
5205 return rc;
5206 }
5207
5208 /*===========================================================================
5209 * FUNCTION : addVideoChannel
5210 *
5211 * DESCRIPTION: add a video channel that contains a video stream
5212 *
5213 * PARAMETERS : none
5214 *
5215 * RETURN : int32_t type of status
5216 * NO_ERROR -- success
5217 * none-zero failure code
5218 *==========================================================================*/
addVideoChannel()5219 int32_t QCamera2HardwareInterface::addVideoChannel()
5220 {
5221 int32_t rc = NO_ERROR;
5222 QCameraVideoChannel *pChannel = NULL;
5223
5224 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
5225 // if we had video channel before, delete it first
5226 delete m_channels[QCAMERA_CH_TYPE_VIDEO];
5227 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
5228 }
5229
5230 pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
5231 mCameraHandle->ops);
5232 if (NULL == pChannel) {
5233 ALOGE("%s: no mem for video channel", __func__);
5234 return NO_MEMORY;
5235 }
5236
5237 // preview only channel, don't need bundle attr and cb
5238 rc = pChannel->init(NULL, NULL, NULL);
5239 if (rc != 0) {
5240 ALOGE("%s: init video channel failed, ret = %d", __func__, rc);
5241 delete pChannel;
5242 return rc;
5243 }
5244
5245 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
5246 video_stream_cb_routine, this);
5247 if (rc != NO_ERROR) {
5248 ALOGE("%s: add video stream failed, ret = %d", __func__, rc);
5249 delete pChannel;
5250 return rc;
5251 }
5252
5253 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
5254 return rc;
5255 }
5256
5257 /*===========================================================================
5258 * FUNCTION : addSnapshotChannel
5259 *
5260 * DESCRIPTION: add a snapshot channel that contains a snapshot stream
5261 *
5262 * PARAMETERS : none
5263 *
5264 * RETURN : int32_t type of status
5265 * NO_ERROR -- success
5266 * none-zero failure code
5267 * NOTE : Add this channel for live snapshot usecase. Regular capture will
5268 * use addCaptureChannel.
5269 *==========================================================================*/
addSnapshotChannel()5270 int32_t QCamera2HardwareInterface::addSnapshotChannel()
5271 {
5272 int32_t rc = NO_ERROR;
5273 QCameraChannel *pChannel = NULL;
5274
5275 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
5276 // if we had ZSL channel before, delete it first
5277 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5278 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
5279 }
5280
5281 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
5282 mCameraHandle->ops);
5283 if (NULL == pChannel) {
5284 ALOGE("%s: no mem for snapshot channel", __func__);
5285 return NO_MEMORY;
5286 }
5287
5288 mm_camera_channel_attr_t attr;
5289 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
5290 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
5291 attr.look_back = mParameters.getZSLBackLookCount();
5292 attr.post_frame_skip = mParameters.getZSLBurstInterval();
5293 attr.water_mark = mParameters.getZSLQueueDepth();
5294 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
5295 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
5296 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
5297 if (rc != NO_ERROR) {
5298 ALOGE("%s: init snapshot channel failed, ret = %d", __func__, rc);
5299 delete pChannel;
5300 return rc;
5301 }
5302
5303 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
5304 NULL, NULL);
5305 if (rc != NO_ERROR) {
5306 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
5307 delete pChannel;
5308 return rc;
5309 }
5310
5311 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
5312 return rc;
5313 }
5314
5315 /*===========================================================================
5316 * FUNCTION : addRawChannel
5317 *
5318 * DESCRIPTION: add a raw channel that contains a raw image stream
5319 *
5320 * PARAMETERS : none
5321 *
5322 * RETURN : int32_t type of status
5323 * NO_ERROR -- success
5324 * none-zero failure code
5325 *==========================================================================*/
addRawChannel()5326 int32_t QCamera2HardwareInterface::addRawChannel()
5327 {
5328 int32_t rc = NO_ERROR;
5329 QCameraChannel *pChannel = NULL;
5330
5331 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
5332 // if we had raw channel before, delete it first
5333 delete m_channels[QCAMERA_CH_TYPE_RAW];
5334 m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
5335 }
5336
5337 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
5338 mCameraHandle->ops);
5339 if (NULL == pChannel) {
5340 ALOGE("%s: no mem for raw channel", __func__);
5341 return NO_MEMORY;
5342 }
5343
5344 rc = pChannel->init(NULL, NULL, NULL);
5345 if (rc != NO_ERROR) {
5346 ALOGE("%s: init raw channel failed, ret = %d", __func__, rc);
5347 delete pChannel;
5348 return rc;
5349 }
5350
5351 // meta data stream always coexists with snapshot in regular RAW capture case
5352 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
5353 metadata_stream_cb_routine, this);
5354 if (rc != NO_ERROR) {
5355 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
5356 delete pChannel;
5357 return rc;
5358 }
5359 waitDefferedWork(mMetadataJob);
5360
5361 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
5362 raw_stream_cb_routine, this);
5363 if (rc != NO_ERROR) {
5364 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
5365 delete pChannel;
5366 return rc;
5367 }
5368 waitDefferedWork(mRawdataJob);
5369 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
5370 return rc;
5371 }
5372
5373 /*===========================================================================
5374 * FUNCTION : addZSLChannel
5375 *
5376 * DESCRIPTION: add a ZSL channel that contains a preview stream and
5377 * a snapshot stream
5378 *
5379 * PARAMETERS : none
5380 *
5381 * RETURN : int32_t type of status
5382 * NO_ERROR -- success
5383 * none-zero failure code
5384 *==========================================================================*/
addZSLChannel()5385 int32_t QCamera2HardwareInterface::addZSLChannel()
5386 {
5387 int32_t rc = NO_ERROR;
5388 QCameraPicChannel *pChannel = NULL;
5389 char value[PROPERTY_VALUE_MAX];
5390 bool raw_yuv = false;
5391
5392 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
5393 // if we had ZSL channel before, delete it first
5394 delete m_channels[QCAMERA_CH_TYPE_ZSL];
5395 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
5396 }
5397
5398 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
5399 mCameraHandle->ops);
5400 if (NULL == pChannel) {
5401 ALOGE("%s: no mem for ZSL channel", __func__);
5402 return NO_MEMORY;
5403 }
5404
5405 // ZSL channel, init with bundle attr and cb
5406 mm_camera_channel_attr_t attr;
5407 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
5408 if (mParameters.isSceneSelectionEnabled()) {
5409 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
5410 } else {
5411 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
5412 }
5413 attr.look_back = mParameters.getZSLBackLookCount();
5414 attr.post_frame_skip = mParameters.getZSLBurstInterval();
5415 attr.water_mark = mParameters.getZSLQueueDepth();
5416 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
5417 rc = pChannel->init(&attr,
5418 zsl_channel_cb,
5419 this);
5420 if (rc != 0) {
5421 ALOGE("%s: init ZSL channel failed, ret = %d", __func__, rc);
5422 delete pChannel;
5423 return rc;
5424 }
5425
5426 // meta data stream always coexists with preview if applicable
5427 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
5428 metadata_stream_cb_routine, this);
5429 if (rc != NO_ERROR) {
5430 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
5431 delete pChannel;
5432 return rc;
5433 }
5434
5435 if (isNoDisplayMode()) {
5436 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
5437 nodisplay_preview_stream_cb_routine, this);
5438 } else {
5439 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
5440 preview_stream_cb_routine, this);
5441 }
5442 if (rc != NO_ERROR) {
5443 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
5444 delete pChannel;
5445 return rc;
5446 }
5447
5448 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
5449 NULL, this);
5450 if (rc != NO_ERROR) {
5451 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
5452 delete pChannel;
5453 return rc;
5454 }
5455
5456 if (!mParameters.isSecureMode()) {
5457 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
5458 NULL, this);
5459 if (rc != NO_ERROR) {
5460 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc);
5461 delete pChannel;
5462 return rc;
5463 }
5464 }
5465
5466 property_get("persist.camera.raw_yuv", value, "0");
5467 raw_yuv = atoi(value) > 0 ? true : false;
5468 if ( raw_yuv ) {
5469 rc = addStreamToChannel(pChannel,
5470 CAM_STREAM_TYPE_RAW,
5471 NULL,
5472 this);
5473 if (rc != NO_ERROR) {
5474 ALOGE("%s: add raw stream failed, ret = %d", __func__, rc);
5475 delete pChannel;
5476 return rc;
5477 }
5478 }
5479
5480 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
5481 return rc;
5482 }
5483
5484 /*===========================================================================
5485 * FUNCTION : addCaptureChannel
5486 *
5487 * DESCRIPTION: add a capture channel that contains a snapshot stream
5488 * and a postview stream
5489 *
5490 * PARAMETERS : none
5491 *
5492 * RETURN : int32_t type of status
5493 * NO_ERROR -- success
5494 * none-zero failure code
5495 * NOTE : Add this channel for regular capture usecase.
5496 * For Live snapshot usecase, use addSnapshotChannel.
5497 *==========================================================================*/
addCaptureChannel()5498 int32_t QCamera2HardwareInterface::addCaptureChannel()
5499 {
5500 int32_t rc = NO_ERROR;
5501 QCameraPicChannel *pChannel = NULL;
5502 char value[PROPERTY_VALUE_MAX];
5503 bool raw_yuv = false;
5504
5505 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
5506 delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
5507 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
5508 }
5509
5510 pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
5511 mCameraHandle->ops);
5512 if (NULL == pChannel) {
5513 ALOGE("%s: no mem for capture channel", __func__);
5514 return NO_MEMORY;
5515 }
5516
5517 // Capture channel, only need snapshot and postview streams start together
5518 mm_camera_channel_attr_t attr;
5519 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
5520 if ( mLongshotEnabled ) {
5521 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
5522 attr.look_back = mParameters.getZSLBackLookCount();
5523 attr.water_mark = mParameters.getZSLQueueDepth();
5524 } else {
5525 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
5526 }
5527 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
5528
5529 rc = pChannel->init(&attr,
5530 capture_channel_cb_routine,
5531 this);
5532 if (rc != NO_ERROR) {
5533 ALOGE("%s: init capture channel failed, ret = %d", __func__, rc);
5534 return rc;
5535 }
5536
5537 // meta data stream always coexists with snapshot in regular capture case
5538 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
5539 metadata_stream_cb_routine, this);
5540 if (rc != NO_ERROR) {
5541 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
5542 return rc;
5543 }
5544
5545 if (!mLongshotEnabled) {
5546 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
5547 NULL, this);
5548
5549 if (rc != NO_ERROR) {
5550 ALOGE("%s: add postview stream failed, ret = %d", __func__, rc);
5551 return rc;
5552 }
5553 } else {
5554 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
5555 preview_stream_cb_routine, this);
5556
5557 if (rc != NO_ERROR) {
5558 ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
5559 return rc;
5560 }
5561 }
5562
5563 if (!mParameters.getofflineRAW()) {
5564 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
5565 NULL, this);
5566 if (rc != NO_ERROR) {
5567 ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
5568 return rc;
5569 }
5570 }
5571 property_get("persist.camera.raw_yuv", value, "0");
5572 raw_yuv = atoi(value) > 0 ? true : false;
5573 if ( raw_yuv ) {
5574 if (!mParameters.getofflineRAW()) {
5575 rc = addStreamToChannel(pChannel,
5576 CAM_STREAM_TYPE_RAW,
5577 snapshot_raw_stream_cb_routine,
5578 this);
5579 } else {
5580 rc = addStreamToChannel(pChannel,
5581 CAM_STREAM_TYPE_RAW,
5582 NULL,
5583 this);
5584 }
5585 if (rc != NO_ERROR) {
5586 ALOGE("%s: add raw stream failed, ret = %d", __func__, rc);
5587 return rc;
5588 }
5589 }
5590
5591 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
5592 return rc;
5593 }
5594
5595 /*===========================================================================
5596 * FUNCTION : addMetaDataChannel
5597 *
5598 * DESCRIPTION: add a meta data channel that contains a metadata stream
5599 *
5600 * PARAMETERS : none
5601 *
5602 * RETURN : int32_t type of status
5603 * NO_ERROR -- success
5604 * none-zero failure code
5605 *==========================================================================*/
addMetaDataChannel()5606 int32_t QCamera2HardwareInterface::addMetaDataChannel()
5607 {
5608 int32_t rc = NO_ERROR;
5609 QCameraChannel *pChannel = NULL;
5610
5611 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
5612 delete m_channels[QCAMERA_CH_TYPE_METADATA];
5613 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
5614 }
5615
5616 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
5617 mCameraHandle->ops);
5618 if (NULL == pChannel) {
5619 ALOGE("%s: no mem for metadata channel", __func__);
5620 return NO_MEMORY;
5621 }
5622
5623 rc = pChannel->init(NULL,
5624 NULL,
5625 NULL);
5626 if (rc != NO_ERROR) {
5627 ALOGE("%s: init metadata channel failed, ret = %d", __func__, rc);
5628 delete pChannel;
5629 return rc;
5630 }
5631
5632 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
5633 metadata_stream_cb_routine, this);
5634 if (rc != NO_ERROR) {
5635 ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
5636 delete pChannel;
5637 return rc;
5638 }
5639
5640 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
5641 return rc;
5642 }
5643
5644 /*===========================================================================
5645 * FUNCTION : addAnalysisChannel
5646 *
5647 * DESCRIPTION: add a analysis channel that contains a analysis stream
5648 *
5649 * PARAMETERS : none
5650 *
5651 * RETURN : int32_t type of status
5652 * NO_ERROR -- success
5653 * none-zero failure code
5654 *==========================================================================*/
addAnalysisChannel()5655 int32_t QCamera2HardwareInterface::addAnalysisChannel()
5656 {
5657 int32_t rc = NO_ERROR;
5658 QCameraChannel *pChannel = NULL;
5659
5660 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
5661 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
5662 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
5663 }
5664
5665 pChannel = new QCameraChannel(mCameraHandle->camera_handle,
5666 mCameraHandle->ops);
5667 if (NULL == pChannel) {
5668 ALOGE("%s: no mem for metadata channel", __func__);
5669 return NO_MEMORY;
5670 }
5671
5672 rc = pChannel->init(NULL, NULL, this);
5673 if (rc != NO_ERROR) {
5674 ALOGE("%s: init Analysis channel failed, ret = %d", __func__, rc);
5675 delete pChannel;
5676 return rc;
5677 }
5678
5679 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
5680 NULL, this);
5681 if (rc != NO_ERROR) {
5682 ALOGE("%s: add Analysis stream failed, ret = %d", __func__, rc);
5683 delete pChannel;
5684 return rc;
5685 }
5686
5687 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
5688 return rc;
5689 }
5690
5691
5692 /*===========================================================================
5693 * FUNCTION : getPPConfig
5694 *
5695 * DESCRIPTION: get Post processing configaration data
5696 *
5697 * PARAMETERS :
5698 * @pp config: pp config structure pointer,
5699 * @curCount: current pp pass count
5700 *
5701 * RETURN : int32_t type of status
5702 * NO_ERROR -- success
5703 * none-zero failure code
5704 *==========================================================================*/
getPPConfig(cam_pp_feature_config_t & pp_config,int curCount)5705 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config, int curCount)
5706 {
5707 int32_t rc = NO_ERROR;
5708
5709 if ( curCount != mParameters.getReprocCount() ) {
5710 ALOGW("%s : Multi pass enabled. Total Pass = %d, cur Pass = %d", __func__,
5711 mParameters.getReprocCount(), curCount);
5712 }
5713
5714 CDBG_HIGH("%s: Minimum pproc feature mask required = %x", __func__,
5715 gCamCaps[mCameraId]->min_required_pp_mask);
5716 uint32_t required_mask = gCamCaps[mCameraId]->min_required_pp_mask;
5717 int32_t zoomLevel = 0;
5718
5719 switch(curCount) {
5720 case 1:
5721 //Configure feature mask for first pass of reprocessing
5722 if (mParameters.isZSLMode() || required_mask & CAM_QCOM_FEATURE_PP_SUPERSET) {
5723 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_EFFECT) {
5724 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
5725 pp_config.effect = mParameters.getEffectValue();
5726 }
5727 if ((gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
5728 !mParameters.isOptiZoomEnabled()) {
5729 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
5730 pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS);
5731 }
5732
5733 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_CROP) {
5734 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
5735 }
5736
5737 if (mParameters.isWNREnabled()) {
5738 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
5739 pp_config.denoise2d.denoise_enable = 1;
5740 pp_config.denoise2d.process_plates =
5741 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
5742 }
5743 if (required_mask & CAM_QCOM_FEATURE_ROTATION) {
5744 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
5745 }
5746 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SCALE) {
5747 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
5748 }
5749 }
5750
5751 if (isCACEnabled()) {
5752 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
5753 }
5754
5755 if (needRotationReprocess()) {
5756 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
5757 uint32_t rotation = mParameters.getJpegRotation();
5758 if (rotation == 0) {
5759 pp_config.rotation = ROTATE_0;
5760 } else if (rotation == 90) {
5761 pp_config.rotation = ROTATE_90;
5762 } else if (rotation == 180) {
5763 pp_config.rotation = ROTATE_180;
5764 } else if (rotation == 270) {
5765 pp_config.rotation = ROTATE_270;
5766 }
5767 }
5768
5769 if (mParameters.isHDREnabled()){
5770 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
5771 pp_config.hdr_param.hdr_enable = 1;
5772 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
5773 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
5774 } else {
5775 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
5776 pp_config.hdr_param.hdr_enable = 0;
5777 }
5778
5779 if(needScaleReprocess()){
5780 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
5781 mParameters.m_reprocScaleParam.getPicSizeFromAPK(
5782 pp_config.scale_param.output_width,
5783 pp_config.scale_param.output_height);
5784 }
5785
5786 if(mParameters.isUbiFocusEnabled()) {
5787 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
5788 } else {
5789 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
5790 }
5791
5792 if(mParameters.isUbiRefocus()) {
5793 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
5794 pp_config.misc_buf_param.misc_buffer_index = 0;
5795 } else {
5796 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
5797 }
5798
5799 if(mParameters.isChromaFlashEnabled()) {
5800 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
5801 pp_config.flash_value = CAM_FLASH_ON;
5802 } else {
5803 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
5804 }
5805
5806 zoomLevel = mParameters.getParmZoomLevel();
5807 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
5808 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
5809 pp_config.zoom_level = (uint8_t) zoomLevel;
5810 } else {
5811 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
5812 }
5813
5814 if (mParameters.getofflineRAW()) {
5815 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
5816 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
5817 }
5818
5819 if (mParameters.isTruePortraitEnabled()) {
5820 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
5821 pp_config.misc_buf_param.misc_buffer_index = 0;
5822 } else {
5823 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
5824 }
5825
5826 if(mParameters.isStillMoreEnabled()) {
5827 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
5828 } else {
5829 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
5830 }
5831
5832 if (curCount != mParameters.getReprocCount()) {
5833 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
5834 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
5835 pp_config.rotation = ROTATE_0;
5836 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
5837 } else {
5838 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
5839 }
5840 break;
5841
5842 case 2:
5843 //Configure feature mask for second pass of reprocessing
5844 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
5845 if (needRotationReprocess()) {
5846 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
5847 uint32_t rotation = mParameters.getJpegRotation();
5848 if (rotation == 0) {
5849 pp_config.rotation = ROTATE_0;
5850 } else if (rotation == 90) {
5851 pp_config.rotation = ROTATE_90;
5852 } else if (rotation == 180) {
5853 pp_config.rotation = ROTATE_180;
5854 } else if (rotation == 270) {
5855 pp_config.rotation = ROTATE_270;
5856 }
5857 }
5858 break;
5859
5860 }
5861 CDBG_HIGH("%s: pproc feature mask set = %x pass count = %d",
5862 __func__, pp_config.feature_mask,curCount);
5863 return rc;
5864 }
5865
5866 /*===========================================================================
5867 * FUNCTION : addReprocChannel
5868 *
5869 * DESCRIPTION: add a reprocess channel that will do reprocess on frames
5870 * coming from input channel
5871 *
5872 * PARAMETERS :
5873 * @pInputChannel : ptr to input channel whose frames will be post-processed
5874 *
5875 * RETURN : Ptr to the newly created channel obj. NULL if failed.
5876 *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel)5877 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
5878 QCameraChannel *pInputChannel)
5879 {
5880 int32_t rc = NO_ERROR;
5881 QCameraReprocessChannel *pChannel = NULL;
5882
5883 if (pInputChannel == NULL) {
5884 ALOGE("%s: input channel obj is NULL", __func__);
5885 return NULL;
5886 }
5887
5888 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
5889 mCameraHandle->ops);
5890 if (NULL == pChannel) {
5891 ALOGE("%s: no mem for reprocess channel", __func__);
5892 return NULL;
5893 }
5894
5895 // Capture channel, only need snapshot and postview streams start together
5896 mm_camera_channel_attr_t attr;
5897 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
5898 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
5899 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
5900 rc = pChannel->init(&attr,
5901 postproc_channel_cb_routine,
5902 this);
5903 if (rc != NO_ERROR) {
5904 ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
5905 delete pChannel;
5906 return NULL;
5907 }
5908
5909 // pp feature config
5910 cam_pp_feature_config_t pp_config;
5911 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
5912
5913 rc = getPPConfig(pp_config, mParameters.getCurPPCount());
5914 if (rc != NO_ERROR){
5915 ALOGE("%s: Error while creating PP config",__func__);
5916 delete pChannel;
5917 return NULL;
5918 }
5919
5920 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
5921
5922 //WNR and HDR happen inline. No extra buffers needed.
5923 uint32_t temp_feature_mask = pp_config.feature_mask;
5924 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
5925 if (temp_feature_mask && mParameters.isHDREnabled()) {
5926 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
5927 }
5928
5929 if (mParameters.isStillMoreEnabled()) {
5930 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
5931 pp_config.burst_cnt = stillmore_config.burst_count;
5932 CDBG_HIGH("%s: Stillmore burst %d", __func__, pp_config.burst_cnt);
5933
5934 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
5935 // number of capture is already added. In the case of liveshot,
5936 // stillmore burst is 1. This is to account for the premature decrement
5937 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
5938 minStreamBufNum += 1;
5939 }
5940 }
5941
5942 // Add non inplace image lib buffers only when ppproc is present,
5943 // becuase pproc is non inplace and input buffers for img lib
5944 // are output for pproc and this number of extra buffers is required
5945 // If pproc is not there, input buffers for imglib are from snapshot stream
5946 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
5947 if (temp_feature_mask && imglib_extra_bufs) {
5948 // 1 is added because getNumOfExtraBuffersForImageProc returns extra
5949 // buffers assuming number of capture is already added
5950 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
5951 }
5952
5953 // If input channel is Snapshot Channel, then update feature mask
5954 if (pInputChannel == m_channels[QCAMERA_CH_TYPE_SNAPSHOT]) {
5955 //Mask out features that are already processed in snapshot stream.
5956 uint32_t snapshot_feature_mask = 0;
5957 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
5958
5959 pp_config.feature_mask &= ~snapshot_feature_mask;
5960 ALOGI("%s: Snapshot feature mask: 0x%x, reproc feature mask: 0x%x", __func__,
5961 snapshot_feature_mask, pp_config.feature_mask);
5962 }
5963
5964 bool offlineReproc = isRegularCapture();
5965 rc = pChannel->addReprocStreamsFromSource(*this,
5966 pp_config,
5967 pInputChannel,
5968 minStreamBufNum,
5969 mParameters.getNumOfSnapshots(),
5970 &gCamCaps[mCameraId]->padding_info,
5971 mParameters,
5972 mLongshotEnabled,
5973 offlineReproc);
5974 if (rc != NO_ERROR) {
5975 delete pChannel;
5976 return NULL;
5977 }
5978
5979 return pChannel;
5980 }
5981
5982 /*===========================================================================
5983 * FUNCTION : addOfflineReprocChannel
5984 *
5985 * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
5986 * that will do reprocess on frames coming from external images
5987 *
5988 * PARAMETERS :
5989 * @img_config : offline reporcess image info
5990 * @pp_feature : pp feature config
5991 *
5992 * RETURN : int32_t type of status
5993 * NO_ERROR -- success
5994 * none-zero failure code
5995 *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)5996 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
5997 cam_pp_offline_src_config_t &img_config,
5998 cam_pp_feature_config_t &pp_feature,
5999 stream_cb_routine stream_cb,
6000 void *userdata)
6001 {
6002 int32_t rc = NO_ERROR;
6003 QCameraReprocessChannel *pChannel = NULL;
6004
6005 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
6006 mCameraHandle->ops);
6007 if (NULL == pChannel) {
6008 ALOGE("%s: no mem for reprocess channel", __func__);
6009 return NULL;
6010 }
6011
6012 rc = pChannel->init(NULL, NULL, NULL);
6013 if (rc != NO_ERROR) {
6014 ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
6015 delete pChannel;
6016 return NULL;
6017 }
6018
6019 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
6020 if (pStreamInfo == NULL) {
6021 ALOGE("%s: no mem for stream info buf", __func__);
6022 delete pChannel;
6023 return NULL;
6024 }
6025
6026 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
6027 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
6028 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
6029 streamInfoBuf->fmt = img_config.input_fmt;
6030 streamInfoBuf->dim = img_config.input_dim;
6031 streamInfoBuf->buf_planes = img_config.input_buf_planes;
6032 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
6033 streamInfoBuf->num_of_burst = img_config.num_of_bufs;
6034
6035 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
6036 streamInfoBuf->reprocess_config.offline = img_config;
6037 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
6038
6039 rc = pChannel->addStream(*this,
6040 pStreamInfo, NULL, img_config.num_of_bufs,
6041 &gCamCaps[mCameraId]->padding_info,
6042 stream_cb, userdata, false);
6043
6044 if (rc != NO_ERROR) {
6045 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
6046 pStreamInfo->deallocate();
6047 delete pStreamInfo;
6048 delete pChannel;
6049 return NULL;
6050 }
6051
6052 return pChannel;
6053 }
6054
6055 /*===========================================================================
6056 * FUNCTION : addChannel
6057 *
6058 * DESCRIPTION: add a channel by its type
6059 *
6060 * PARAMETERS :
6061 * @ch_type : channel type
6062 *
6063 * RETURN : int32_t type of status
6064 * NO_ERROR -- success
6065 * none-zero failure code
6066 *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)6067 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
6068 {
6069 int32_t rc = UNKNOWN_ERROR;
6070 switch (ch_type) {
6071 case QCAMERA_CH_TYPE_ZSL:
6072 rc = addZSLChannel();
6073 break;
6074 case QCAMERA_CH_TYPE_CAPTURE:
6075 rc = addCaptureChannel();
6076 break;
6077 case QCAMERA_CH_TYPE_PREVIEW:
6078 rc = addPreviewChannel();
6079 break;
6080 case QCAMERA_CH_TYPE_VIDEO:
6081 rc = addVideoChannel();
6082 break;
6083 case QCAMERA_CH_TYPE_SNAPSHOT:
6084 rc = addSnapshotChannel();
6085 break;
6086 case QCAMERA_CH_TYPE_RAW:
6087 rc = addRawChannel();
6088 break;
6089 case QCAMERA_CH_TYPE_METADATA:
6090 rc = addMetaDataChannel();
6091 break;
6092 case QCAMERA_CH_TYPE_ANALYSIS:
6093 rc = addAnalysisChannel();
6094 break;
6095 default:
6096 break;
6097 }
6098 return rc;
6099 }
6100
6101 /*===========================================================================
6102 * FUNCTION : delChannel
6103 *
6104 * DESCRIPTION: delete a channel by its type
6105 *
6106 * PARAMETERS :
6107 * @ch_type : channel type
6108 * @destroy : delete context as well
6109 *
6110 * RETURN : int32_t type of status
6111 * NO_ERROR -- success
6112 * none-zero failure code
6113 *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)6114 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
6115 bool destroy)
6116 {
6117 if (m_channels[ch_type] != NULL) {
6118 if (destroy) {
6119 delete m_channels[ch_type];
6120 m_channels[ch_type] = NULL;
6121 } else {
6122 m_channels[ch_type]->deleteChannel();
6123 }
6124 }
6125
6126 return NO_ERROR;
6127 }
6128
6129 /*===========================================================================
6130 * FUNCTION : startChannel
6131 *
6132 * DESCRIPTION: start a channel by its type
6133 *
6134 * PARAMETERS :
6135 * @ch_type : channel type
6136 *
6137 * RETURN : int32_t type of status
6138 * NO_ERROR -- success
6139 * none-zero failure code
6140 *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)6141 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
6142 {
6143 int32_t rc = UNKNOWN_ERROR;
6144 if (m_channels[ch_type] != NULL) {
6145 rc = m_channels[ch_type]->config();
6146 if (NO_ERROR == rc) {
6147 rc = m_channels[ch_type]->start();
6148 }
6149 }
6150
6151 return rc;
6152 }
6153
6154 /*===========================================================================
6155 * FUNCTION : stopChannel
6156 *
6157 * DESCRIPTION: stop a channel by its type
6158 *
6159 * PARAMETERS :
6160 * @ch_type : channel type
6161 *
6162 * RETURN : int32_t type of status
6163 * NO_ERROR -- success
6164 * none-zero failure code
6165 *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)6166 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
6167 {
6168 int32_t rc = UNKNOWN_ERROR;
6169 if (m_channels[ch_type] != NULL) {
6170 rc = m_channels[ch_type]->stop();
6171 }
6172
6173 return rc;
6174 }
6175
6176 /*===========================================================================
6177 * FUNCTION : preparePreview
6178 *
6179 * DESCRIPTION: add channels needed for preview
6180 *
6181 * PARAMETERS : none
6182 *
6183 * RETURN : int32_t type of status
6184 * NO_ERROR -- success
6185 * none-zero failure code
6186 *==========================================================================*/
preparePreview()6187 int32_t QCamera2HardwareInterface::preparePreview()
6188 {
6189 ATRACE_CALL();
6190 int32_t rc = NO_ERROR;
6191
6192 pthread_mutex_lock(&m_parm_lock);
6193 rc = mParameters.setStreamConfigure(false, false, false);
6194 if (rc != NO_ERROR) {
6195 ALOGE("%s: setStreamConfigure failed %d", __func__, rc);
6196 pthread_mutex_unlock(&m_parm_lock);
6197 return rc;
6198 }
6199 pthread_mutex_unlock(&m_parm_lock);
6200
6201 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
6202 rc = addChannel(QCAMERA_CH_TYPE_ZSL);
6203 if (rc != NO_ERROR) {
6204 ALOGE("%s[%d]: failed!! rc = %d", __func__, __LINE__, rc);
6205 return rc;
6206 }
6207 } else {
6208 bool recordingHint = mParameters.getRecordingHintValue();
6209 if(!isRdiMode() && recordingHint) {
6210 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
6211 if (rc != NO_ERROR) {
6212 return rc;
6213 }
6214 rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
6215 if (rc != NO_ERROR) {
6216 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
6217 ALOGE("%s[%d]:failed!! rc = %d", __func__, __LINE__, rc);
6218 return rc;
6219 }
6220 }
6221
6222 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
6223 if (!isRdiMode() && (rc != NO_ERROR)) {
6224 if (recordingHint) {
6225 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
6226 delChannel(QCAMERA_CH_TYPE_VIDEO);
6227 }
6228 }
6229
6230 if (!recordingHint && !mParameters.isSecureMode()) {
6231 waitDefferedWork(mMetadataJob);
6232 waitDefferedWork(mRawdataJob);
6233 }
6234
6235 if (NO_ERROR != rc) {
6236 delChannel(QCAMERA_CH_TYPE_PREVIEW);
6237 ALOGE("%s[%d]:failed!! rc = %d", __func__, __LINE__, rc);
6238 }
6239 }
6240
6241 return rc;
6242 }
6243
6244 /*===========================================================================
6245 * FUNCTION : unpreparePreview
6246 *
6247 * DESCRIPTION: delete channels for preview
6248 *
6249 * PARAMETERS : none
6250 *
6251 * RETURN : none
6252 *==========================================================================*/
unpreparePreview()6253 void QCamera2HardwareInterface::unpreparePreview()
6254 {
6255 delChannel(QCAMERA_CH_TYPE_ZSL);
6256 delChannel(QCAMERA_CH_TYPE_PREVIEW);
6257 delChannel(QCAMERA_CH_TYPE_VIDEO);
6258 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
6259 }
6260
6261 /*===========================================================================
6262 * FUNCTION : playShutter
6263 *
6264 * DESCRIPTION: send request to play shutter sound
6265 *
6266 * PARAMETERS : none
6267 *
6268 * RETURN : none
6269 *==========================================================================*/
playShutter()6270 void QCamera2HardwareInterface::playShutter(){
6271 if (mNotifyCb == NULL ||
6272 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
6273 CDBG("%s: shutter msg not enabled or NULL cb", __func__);
6274 return;
6275 }
6276
6277 qcamera_callback_argm_t cbArg;
6278 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6279 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
6280 cbArg.msg_type = CAMERA_MSG_SHUTTER;
6281 cbArg.ext1 = 0;
6282 cbArg.ext2 = false;
6283 m_cbNotifier.notifyCallback(cbArg);
6284 }
6285
6286 /*===========================================================================
6287 * FUNCTION : getChannelByHandle
6288 *
6289 * DESCRIPTION: return a channel by its handle
6290 *
6291 * PARAMETERS :
6292 * @channelHandle : channel handle
6293 *
6294 * RETURN : a channel obj if found, NULL if not found
6295 *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)6296 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
6297 {
6298 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6299 if (m_channels[i] != NULL &&
6300 m_channels[i]->getMyHandle() == channelHandle) {
6301 return m_channels[i];
6302 }
6303 }
6304
6305 return NULL;
6306 }
6307
6308 /*===========================================================================
6309 * FUNCTION : processFaceDetectionReuslt
6310 *
6311 * DESCRIPTION: process face detection reuslt
6312 *
6313 * PARAMETERS :
6314 * @fd_data : ptr to face detection result struct
6315 *
6316 * RETURN : int32_t type of status
6317 * NO_ERROR -- success
6318 * none-zero failure code
6319 *==========================================================================*/
processFaceDetectionResult(cam_face_detection_data_t * fd_data)6320 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_face_detection_data_t *fd_data)
6321 {
6322 if (!mParameters.isFaceDetectionEnabled()) {
6323 CDBG_HIGH("%s: FaceDetection not enabled, no ops here", __func__);
6324 return NO_ERROR;
6325 }
6326
6327 qcamera_face_detect_type_t fd_type = fd_data->fd_type;
6328 if ((NULL == mDataCb) ||
6329 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA))
6330 #ifndef VANILLA_HAL
6331 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
6332 #endif
6333 ) {
6334 CDBG_HIGH("%s: metadata msgtype not enabled, no ops here", __func__);
6335 return NO_ERROR;
6336 }
6337
6338 cam_dimension_t display_dim;
6339 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
6340 if (display_dim.width <= 0 || display_dim.height <= 0) {
6341 ALOGE("%s: Invalid preview width or height (%d x %d)",
6342 __func__, display_dim.width, display_dim.height);
6343 return UNKNOWN_ERROR;
6344 }
6345
6346 // process face detection result
6347 // need separate face detection in preview or snapshot type
6348 size_t faceResultSize = 0;
6349 size_t data_len = 0;
6350 if(fd_type == QCAMERA_FD_PREVIEW){
6351 //fd for preview frames
6352 faceResultSize = sizeof(camera_frame_metadata_t);
6353 faceResultSize += sizeof(camera_face_t) * MAX_ROI;
6354 }else if(fd_type == QCAMERA_FD_SNAPSHOT){
6355 #ifndef VANILLA_HAL
6356 // fd for snapshot frames
6357 //check if face is detected in this frame
6358 if(fd_data->num_faces_detected > 0){
6359 data_len = sizeof(camera_frame_metadata_t) +
6360 sizeof(camera_face_t) * fd_data->num_faces_detected;
6361 }else{
6362 //no face
6363 data_len = 0;
6364 }
6365 #endif
6366 faceResultSize = 1 *sizeof(int) //meta data type
6367 + 1 *sizeof(int) // meta data len
6368 + data_len; //data
6369 }
6370
6371 camera_memory_t *faceResultBuffer = mGetMemory(-1,
6372 faceResultSize,
6373 1,
6374 mCallbackCookie);
6375 if ( NULL == faceResultBuffer ) {
6376 ALOGE("%s: Not enough memory for face result data",
6377 __func__);
6378 return NO_MEMORY;
6379 }
6380
6381 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
6382 memset(pFaceResult, 0, faceResultSize);
6383 unsigned char *faceData = NULL;
6384 if(fd_type == QCAMERA_FD_PREVIEW){
6385 faceData = pFaceResult;
6386 }else if(fd_type == QCAMERA_FD_SNAPSHOT){
6387 #ifndef VANILLA_HAL
6388 //need fill meta type and meta data len first
6389 int *data_header = (int* )pFaceResult;
6390 data_header[0] = CAMERA_META_DATA_FD;
6391 data_header[1] = (int)data_len;
6392
6393 if(data_len <= 0){
6394 //if face is not valid or do not have face, return
6395 qcamera_callback_argm_t cbArg;
6396 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6397 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6398 cbArg.msg_type = CAMERA_MSG_META_DATA;
6399 cbArg.data = faceResultBuffer;
6400 cbArg.user_data = faceResultBuffer;
6401 cbArg.cookie = this;
6402 cbArg.release_cb = releaseCameraMemory;
6403 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
6404 if (rc != NO_ERROR) {
6405 ALOGE("%s: fail sending notification", __func__);
6406 faceResultBuffer->release(faceResultBuffer);
6407 }
6408 return rc;
6409 }
6410 #endif
6411 faceData = pFaceResult + 2 *sizeof(int); //skip two int length
6412 }
6413
6414 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
6415 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
6416
6417 roiData->number_of_faces = fd_data->num_faces_detected;
6418 roiData->faces = faces;
6419 if (roiData->number_of_faces > 0) {
6420 for (int i = 0; i < roiData->number_of_faces; i++) {
6421 faces[i].id = fd_data->faces[i].face_id;
6422 faces[i].score = fd_data->faces[i].score;
6423
6424 // left
6425 faces[i].rect[0] =
6426 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.left, display_dim.width, 2000, -1000);
6427
6428 // top
6429 faces[i].rect[1] =
6430 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.top, display_dim.height, 2000, -1000);
6431
6432 // right
6433 faces[i].rect[2] = faces[i].rect[0] +
6434 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.width, display_dim.width, 2000, 0);
6435
6436 // bottom
6437 faces[i].rect[3] = faces[i].rect[1] +
6438 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.height, display_dim.height, 2000, 0);
6439
6440 // Center of left eye
6441 faces[i].left_eye[0] =
6442 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.x, display_dim.width, 2000, -1000);
6443
6444 faces[i].left_eye[1] =
6445 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.y, display_dim.height, 2000, -1000);
6446
6447 // Center of right eye
6448 faces[i].right_eye[0] =
6449 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.x, display_dim.width, 2000, -1000);
6450
6451 faces[i].right_eye[1] =
6452 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.y, display_dim.height, 2000, -1000);
6453
6454 // Center of mouth
6455 faces[i].mouth[0] =
6456 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.x, display_dim.width, 2000, -1000);
6457
6458 faces[i].mouth[1] =
6459 MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.y, display_dim.height, 2000, -1000);
6460
6461 #ifndef VANILLA_HAL
6462 faces[i].smile_degree = fd_data->faces[i].smile_degree;
6463 faces[i].smile_score = fd_data->faces[i].smile_confidence;
6464 faces[i].blink_detected = fd_data->faces[i].blink_detected;
6465 faces[i].face_recognised = fd_data->faces[i].face_recognised;
6466 faces[i].gaze_angle = fd_data->faces[i].gaze_angle;
6467
6468 // upscale by 2 to recover from demaen downscaling
6469 faces[i].updown_dir = fd_data->faces[i].updown_dir * 2;
6470 faces[i].leftright_dir = fd_data->faces[i].leftright_dir * 2;
6471 faces[i].roll_dir = fd_data->faces[i].roll_dir * 2;
6472
6473 faces[i].leye_blink = fd_data->faces[i].left_blink;
6474 faces[i].reye_blink = fd_data->faces[i].right_blink;
6475 faces[i].left_right_gaze = fd_data->faces[i].left_right_gaze;
6476 faces[i].top_bottom_gaze = fd_data->faces[i].top_bottom_gaze;
6477 #endif
6478
6479 }
6480 }
6481
6482 qcamera_callback_argm_t cbArg;
6483 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6484 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6485 if(fd_type == QCAMERA_FD_PREVIEW){
6486 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
6487 }
6488 #ifndef VANILLA_HAL
6489 else if(fd_type == QCAMERA_FD_SNAPSHOT){
6490 cbArg.msg_type = CAMERA_MSG_META_DATA;
6491 }
6492 #endif
6493 cbArg.data = faceResultBuffer;
6494 cbArg.metadata = roiData;
6495 cbArg.user_data = faceResultBuffer;
6496 cbArg.cookie = this;
6497 cbArg.release_cb = releaseCameraMemory;
6498 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
6499 if (rc != NO_ERROR) {
6500 ALOGE("%s: fail sending notification", __func__);
6501 faceResultBuffer->release(faceResultBuffer);
6502 }
6503
6504 return rc;
6505 }
6506
6507 /*===========================================================================
6508 * FUNCTION : releaseCameraMemory
6509 *
6510 * DESCRIPTION: releases camera memory objects
6511 *
6512 * PARAMETERS :
6513 * @data : buffer to be released
6514 * @cookie : context data
6515 * @cbStatus: callback status
6516 *
6517 * RETURN : None
6518 *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)6519 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
6520 void */*cookie*/,
6521 int32_t /*cbStatus*/)
6522 {
6523 camera_memory_t *mem = ( camera_memory_t * ) data;
6524 if ( NULL != mem ) {
6525 mem->release(mem);
6526 }
6527 }
6528
6529 /*===========================================================================
6530 * FUNCTION : returnStreamBuffer
6531 *
6532 * DESCRIPTION: returns back a stream buffer
6533 *
6534 * PARAMETERS :
6535 * @data : buffer to be released
6536 * @cookie : context data
6537 * @cbStatus: callback status
6538 *
6539 * RETURN : None
6540 *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)6541 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
6542 void *cookie,
6543 int32_t /*cbStatus*/)
6544 {
6545 QCameraStream *stream = ( QCameraStream * ) cookie;
6546 int idx = *((int *)data);
6547 if ((NULL != stream) && (0 <= idx)) {
6548 stream->bufDone((uint32_t)idx);
6549 } else {
6550 ALOGE("%s: Cannot return buffer %d %p", __func__, idx, cookie);
6551 }
6552 }
6553
6554 /*===========================================================================
6555 * FUNCTION : processHistogramStats
6556 *
6557 * DESCRIPTION: process histogram stats
6558 *
6559 * PARAMETERS :
6560 * @hist_data : ptr to histogram stats struct
6561 *
6562 * RETURN : int32_t type of status
6563 * NO_ERROR -- success
6564 * none-zero failure code
6565 *==========================================================================*/
processHistogramStats(cam_hist_stats_t & stats_data)6566 int32_t QCamera2HardwareInterface::processHistogramStats(cam_hist_stats_t &stats_data)
6567 {
6568 #ifndef VANILLA_HAL
6569 if (!mParameters.isHistogramEnabled()) {
6570 CDBG_HIGH("%s: Histogram not enabled, no ops here", __func__);
6571 return NO_ERROR;
6572 }
6573
6574 camera_memory_t *histBuffer = mGetMemory(-1,
6575 sizeof(cam_histogram_data_t),
6576 1,
6577 mCallbackCookie);
6578 if ( NULL == histBuffer ) {
6579 ALOGE("%s: Not enough memory for histogram data",
6580 __func__);
6581 return NO_MEMORY;
6582 }
6583
6584 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
6585 if (pHistData == NULL) {
6586 ALOGE("%s: memory data ptr is NULL", __func__);
6587 return UNKNOWN_ERROR;
6588 }
6589
6590 switch (stats_data.type) {
6591 case CAM_HISTOGRAM_TYPE_BAYER:
6592 *pHistData = stats_data.bayer_stats.gb_stats;
6593 break;
6594 case CAM_HISTOGRAM_TYPE_YUV:
6595 *pHistData = stats_data.yuv_stats;
6596 break;
6597 }
6598
6599 qcamera_callback_argm_t cbArg;
6600 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6601 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6602 cbArg.msg_type = CAMERA_MSG_STATS_DATA;
6603 cbArg.data = histBuffer;
6604 cbArg.user_data = histBuffer;
6605 cbArg.cookie = this;
6606 cbArg.release_cb = releaseCameraMemory;
6607 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
6608 if (rc != NO_ERROR) {
6609 ALOGE("%s: fail sending notification", __func__);
6610 histBuffer->release(histBuffer);
6611 }
6612 #endif
6613 return NO_ERROR;
6614 }
6615
6616 /*===========================================================================
6617 * FUNCTION : calcThermalLevel
6618 *
6619 * DESCRIPTION: Calculates the target fps range depending on
6620 * the thermal level.
6621 *
6622 * PARAMETERS :
6623 * @level : received thermal level
6624 * @minFPS : minimum configured fps range
6625 * @maxFPS : maximum configured fps range
6626 * @adjustedRange : target fps range
6627 * @skipPattern : target skip pattern
6628 *
6629 * RETURN : int32_t type of status
6630 * NO_ERROR -- success
6631 * none-zero failure code
6632 *==========================================================================*/
calcThermalLevel(qcamera_thermal_level_enum_t level,const int minFPSi,const int maxFPSi,cam_fps_range_t & adjustedRange,enum msm_vfe_frame_skip_pattern & skipPattern)6633 int QCamera2HardwareInterface::calcThermalLevel(
6634 qcamera_thermal_level_enum_t level,
6635 const int minFPSi,
6636 const int maxFPSi,
6637 cam_fps_range_t &adjustedRange,
6638 enum msm_vfe_frame_skip_pattern &skipPattern)
6639 {
6640 const float minFPS = (float)minFPSi;
6641 const float maxFPS = (float)maxFPSi;
6642
6643 // Initialize video fps to preview fps
6644 float minVideoFps = minFPS, maxVideoFps = maxFPS;
6645 cam_fps_range_t videoFps;
6646 // If HFR mode, update video fps accordingly
6647 if(isHFRMode()) {
6648 mParameters.getHfrFps(videoFps);
6649 minVideoFps = videoFps.video_min_fps;
6650 maxVideoFps = videoFps.video_max_fps;
6651 }
6652
6653 CDBG_HIGH("%s: level: %d, preview minfps %f, preview maxfpS %f, "
6654 "video minfps %f, video maxfpS %f",
6655 __func__, level, minFPS, maxFPS, minVideoFps, maxVideoFps);
6656
6657 switch(level) {
6658 case QCAMERA_THERMAL_NO_ADJUSTMENT:
6659 {
6660 adjustedRange.min_fps = minFPS / 1000.0f;
6661 adjustedRange.max_fps = maxFPS / 1000.0f;
6662 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
6663 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
6664 skipPattern = NO_SKIP;
6665 }
6666 break;
6667 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
6668 {
6669 adjustedRange.min_fps = minFPS / 1000.0f;
6670 adjustedRange.max_fps = maxFPS / 1000.0f;
6671 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
6672 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
6673 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
6674 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
6675 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
6676 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
6677 if ( adjustedRange.min_fps < 1 ) {
6678 adjustedRange.min_fps = 1;
6679 }
6680 if ( adjustedRange.max_fps < 1 ) {
6681 adjustedRange.max_fps = 1;
6682 }
6683 if ( adjustedRange.video_min_fps < 1 ) {
6684 adjustedRange.video_min_fps = 1;
6685 }
6686 if ( adjustedRange.video_max_fps < 1 ) {
6687 adjustedRange.video_max_fps = 1;
6688 }
6689 skipPattern = EVERY_2FRAME;
6690 }
6691 break;
6692 case QCAMERA_THERMAL_BIG_ADJUSTMENT:
6693 {
6694 adjustedRange.min_fps = minFPS / 1000.0f;
6695 adjustedRange.max_fps = maxFPS / 1000.0f;
6696 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
6697 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
6698 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
6699 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
6700 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
6701 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
6702 if ( adjustedRange.min_fps < 1 ) {
6703 adjustedRange.min_fps = 1;
6704 }
6705 if ( adjustedRange.max_fps < 1 ) {
6706 adjustedRange.max_fps = 1;
6707 }
6708 if ( adjustedRange.video_min_fps < 1 ) {
6709 adjustedRange.video_min_fps = 1;
6710 }
6711 if ( adjustedRange.video_max_fps < 1 ) {
6712 adjustedRange.video_max_fps = 1;
6713 }
6714 skipPattern = EVERY_4FRAME;
6715 }
6716 break;
6717 case QCAMERA_THERMAL_SHUTDOWN:
6718 {
6719 // Stop Preview?
6720 // Set lowest min FPS for now
6721 adjustedRange.min_fps = minFPS/1000.0f;
6722 adjustedRange.max_fps = minFPS/1000.0f;
6723 for (size_t i = 0; i < gCamCaps[mCameraId]->fps_ranges_tbl_cnt; i++) {
6724 if (gCamCaps[mCameraId]->fps_ranges_tbl[i].min_fps < adjustedRange.min_fps) {
6725 adjustedRange.min_fps = gCamCaps[mCameraId]->fps_ranges_tbl[i].min_fps;
6726 adjustedRange.max_fps = adjustedRange.min_fps;
6727 }
6728 }
6729 skipPattern = MAX_SKIP;
6730 adjustedRange.video_min_fps = adjustedRange.min_fps;
6731 adjustedRange.video_max_fps = adjustedRange.max_fps;
6732 }
6733 break;
6734 default:
6735 {
6736 ALOGE("%s: Invalid thermal level %d", __func__, level);
6737 return BAD_VALUE;
6738 }
6739 break;
6740 }
6741 CDBG_HIGH("%s: Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
6742 __func__, level, adjustedRange.min_fps, adjustedRange.max_fps,
6743 adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
6744
6745 return NO_ERROR;
6746 }
6747
6748 /*===========================================================================
6749 * FUNCTION : recalcFPSRange
6750 *
6751 * DESCRIPTION: adjust the configured fps range regarding
6752 * the last thermal level.
6753 *
6754 * PARAMETERS :
6755 * @minFPS : minimum configured fps range
6756 * @maxFPS : maximum configured fps range
6757 * @adjustedRange : target fps range
6758 *
6759 * RETURN : int32_t type of status
6760 * NO_ERROR -- success
6761 * none-zero failure code
6762 *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,cam_fps_range_t & adjustedRange)6763 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
6764 cam_fps_range_t &adjustedRange)
6765 {
6766 enum msm_vfe_frame_skip_pattern skipPattern;
6767 calcThermalLevel(mThermalLevel,
6768 minFPS,
6769 maxFPS,
6770 adjustedRange,
6771 skipPattern);
6772 return NO_ERROR;
6773 }
6774
6775 /*===========================================================================
6776 * FUNCTION : updateThermalLevel
6777 *
6778 * DESCRIPTION: update thermal level depending on thermal events
6779 *
6780 * PARAMETERS :
6781 * @level : thermal level
6782 *
6783 * RETURN : int32_t type of status
6784 * NO_ERROR -- success
6785 * none-zero failure code
6786 *==========================================================================*/
updateThermalLevel(void * thermal_level)6787 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
6788 {
6789 int ret = NO_ERROR;
6790 cam_fps_range_t adjustedRange;
6791 int minFPS, maxFPS;
6792 enum msm_vfe_frame_skip_pattern skipPattern;
6793 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
6794
6795 pthread_mutex_lock(&m_parm_lock);
6796
6797 if (!mCameraOpened) {
6798 CDBG_HIGH("%s: Camera is not opened, no need to update camera parameters", __func__);
6799 pthread_mutex_unlock(&m_parm_lock);
6800 return NO_ERROR;
6801 }
6802
6803 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
6804 qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
6805 calcThermalLevel(level, minFPS, maxFPS, adjustedRange, skipPattern);
6806 mThermalLevel = level;
6807
6808 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
6809 ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
6810 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
6811 ret = mParameters.setFrameSkip(skipPattern);
6812 else
6813 ALOGE("%s: Incorrect thermal mode %d", __func__, thermalMode);
6814
6815 pthread_mutex_unlock(&m_parm_lock);
6816
6817 return ret;
6818
6819 }
6820
6821 /*===========================================================================
6822 * FUNCTION : updateParameters
6823 *
6824 * DESCRIPTION: update parameters
6825 *
6826 * PARAMETERS :
6827 * @parms : input parameters string
6828 * @needRestart : output, flag to indicate if preview restart is needed
6829 *
6830 * RETURN : int32_t type of status
6831 * NO_ERROR -- success
6832 * none-zero failure code
6833 *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)6834 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
6835 {
6836 int rc = NO_ERROR;
6837 pthread_mutex_lock(&m_parm_lock);
6838 String8 str = String8(parms);
6839 QCameraParameters param(str);
6840 rc = mParameters.updateParameters(param, needRestart);
6841
6842 // update stream based parameter settings
6843 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6844 if (m_channels[i] != NULL) {
6845 m_channels[i]->UpdateStreamBasedParameters(mParameters);
6846 }
6847 }
6848 pthread_mutex_unlock(&m_parm_lock);
6849
6850 return rc;
6851 }
6852
6853 /*===========================================================================
6854 * FUNCTION : commitParameterChanges
6855 *
6856 * DESCRIPTION: commit parameter changes to the backend to take effect
6857 *
6858 * PARAMETERS : none
6859 *
6860 * RETURN : int32_t type of status
6861 * NO_ERROR -- success
6862 * none-zero failure code
6863 * NOTE : This function must be called after updateParameters.
6864 * Otherwise, no change will be passed to backend to take effect.
6865 *==========================================================================*/
commitParameterChanges()6866 int QCamera2HardwareInterface::commitParameterChanges()
6867 {
6868 int rc = NO_ERROR;
6869 pthread_mutex_lock(&m_parm_lock);
6870 rc = mParameters.commitParameters();
6871 if (rc == NO_ERROR) {
6872 // update number of snapshot based on committed parameters setting
6873 rc = mParameters.setNumOfSnapshot();
6874 }
6875 pthread_mutex_unlock(&m_parm_lock);
6876 return rc;
6877 }
6878
6879 /*===========================================================================
6880 * FUNCTION : needDebugFps
6881 *
6882 * DESCRIPTION: if fps log info need to be printed out
6883 *
6884 * PARAMETERS : none
6885 *
6886 * RETURN : true: need print out fps log
6887 * false: no need to print out fps log
6888 *==========================================================================*/
needDebugFps()6889 bool QCamera2HardwareInterface::needDebugFps()
6890 {
6891 bool needFps = false;
6892 pthread_mutex_lock(&m_parm_lock);
6893 needFps = mParameters.isFpsDebugEnabled();
6894 pthread_mutex_unlock(&m_parm_lock);
6895 return needFps;
6896 }
6897
6898 /*===========================================================================
6899 * FUNCTION : isCACEnabled
6900 *
6901 * DESCRIPTION: if CAC is enabled
6902 *
6903 * PARAMETERS : none
6904 *
6905 * RETURN : true: needed
6906 * false: no need
6907 *==========================================================================*/
isCACEnabled()6908 bool QCamera2HardwareInterface::isCACEnabled()
6909 {
6910 char prop[PROPERTY_VALUE_MAX];
6911 memset(prop, 0, sizeof(prop));
6912 property_get("persist.camera.feature.cac", prop, "0");
6913 int enableCAC = atoi(prop);
6914 return enableCAC == 1;
6915 }
6916
6917 /*===========================================================================
6918 * FUNCTION : is4k2kResolution
6919 *
6920 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
6921 *
6922 * PARAMETERS : none
6923 *
6924 * RETURN : true: needed
6925 * false: no need
6926 *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)6927 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
6928 {
6929 bool enabled = false;
6930 if ((resolution->width == 4096 && resolution->height == 2160) ||
6931 (resolution->width == 3840 && resolution->height == 2160) ) {
6932 enabled = true;
6933 }
6934 return enabled;
6935 }
6936
6937
6938 /*===========================================================================
6939 * FUNCTION : isAFRunning
6940 *
6941 * DESCRIPTION: if AF is in progress while in Auto/Macro focus modes
6942 *
6943 * PARAMETERS : none
6944 *
6945 * RETURN : true: AF in progress
6946 * false: AF not in progress
6947 *==========================================================================*/
isAFRunning()6948 bool QCamera2HardwareInterface::isAFRunning()
6949 {
6950 bool isAFInProgress = (m_currentFocusState == CAM_AF_SCANNING &&
6951 (mParameters.getFocusMode() == CAM_FOCUS_MODE_AUTO ||
6952 mParameters.getFocusMode() == CAM_FOCUS_MODE_MACRO));
6953
6954 return isAFInProgress;
6955 }
6956
6957 /*===========================================================================
6958 * FUNCTION : isPreviewRestartEnabled
6959 *
6960 * DESCRIPTION: Check whether preview should be restarted automatically
6961 * during image capture.
6962 *
6963 * PARAMETERS : none
6964 *
6965 * RETURN : true: needed
6966 * false: no need
6967 *==========================================================================*/
isPreviewRestartEnabled()6968 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
6969 {
6970 char prop[PROPERTY_VALUE_MAX];
6971 memset(prop, 0, sizeof(prop));
6972 property_get("persist.camera.feature.restart", prop, "0");
6973 int earlyRestart = atoi(prop);
6974 return earlyRestart == 1;
6975 }
6976
6977 /*===========================================================================
6978 * FUNCTION : needReprocess
6979 *
6980 * DESCRIPTION: if reprocess is needed
6981 *
6982 * PARAMETERS : none
6983 *
6984 * RETURN : true: needed
6985 * false: no need
6986 *==========================================================================*/
needReprocess()6987 bool QCamera2HardwareInterface::needReprocess()
6988 {
6989 pthread_mutex_lock(&m_parm_lock);
6990
6991 if (mParameters.getofflineRAW()) {
6992 pthread_mutex_unlock(&m_parm_lock);
6993 return true;
6994 }
6995 if (!mParameters.isJpegPictureFormat() &&
6996 !mParameters.isNV21PictureFormat()) {
6997 // RAW image, no need to reprocess
6998 pthread_mutex_unlock(&m_parm_lock);
6999 return false;
7000 }
7001
7002 if (mParameters.isHDREnabled()) {
7003 CDBG_HIGH("%s: need do reprocess for HDR", __func__);
7004 pthread_mutex_unlock(&m_parm_lock);
7005 return true;
7006 }
7007 //Disable reprocess for 4K liveshot case
7008 if (mParameters.is4k2kVideoResolution()&& mParameters.getRecordingHintValue()) {
7009 //Disable reprocess for 4K liveshot case
7010 pthread_mutex_unlock(&m_parm_lock);
7011 return false;
7012 }
7013 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
7014 (mParameters.getJpegRotation() > 0)) {
7015 // current rotation is not zero, and pp has the capability to process rotation
7016 CDBG_HIGH("%s: need to do reprocess for rotation=%d",
7017 __func__, mParameters.getJpegRotation());
7018 pthread_mutex_unlock(&m_parm_lock);
7019 return true;
7020 }
7021
7022 if (isZSLMode()) {
7023 if (((gCamCaps[mCameraId]->min_required_pp_mask > 0) ||
7024 mParameters.isWNREnabled() || isCACEnabled())) {
7025 // TODO: add for ZSL HDR later
7026 CDBG_HIGH("%s: need do reprocess for ZSL WNR or min PP reprocess", __func__);
7027 pthread_mutex_unlock(&m_parm_lock);
7028 return true;
7029 }
7030
7031 int snapshot_flipMode =
7032 mParameters.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
7033 if (snapshot_flipMode > 0) {
7034 CDBG_HIGH("%s: Need do flip for snapshot in ZSL mode", __func__);
7035 pthread_mutex_unlock(&m_parm_lock);
7036 return true;
7037 }
7038 } else {
7039 if (gCamCaps[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_PP_SUPERSET) {
7040 CDBG_HIGH("%s: Need CPP in non-ZSL mode", __func__);
7041 pthread_mutex_unlock(&m_parm_lock);
7042 return true;
7043 }
7044 }
7045
7046 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SCALE) > 0 &&
7047 mParameters.m_reprocScaleParam.isScaleEnabled() &&
7048 mParameters.m_reprocScaleParam.isUnderScaling()) {
7049 // Reproc Scale is enaled and also need Scaling to current Snapshot
7050 CDBG_HIGH("%s: need do reprocess for scale", __func__);
7051 pthread_mutex_unlock(&m_parm_lock);
7052 return true;
7053 }
7054
7055 if (mParameters.isUbiFocusEnabled() |
7056 mParameters.isUbiRefocus() |
7057 mParameters.isChromaFlashEnabled() |
7058 mParameters.isHDREnabled() |
7059 mParameters.isOptiZoomEnabled() |
7060 mParameters.isStillMoreEnabled()) {
7061 CDBG_HIGH("%s: need reprocess for |UbiFocus=%d|ChramaFlash=%d|OptiZoom=%d|StillMore=%d|",
7062 __func__,
7063 mParameters.isUbiFocusEnabled(),
7064 mParameters.isChromaFlashEnabled(),
7065 mParameters.isOptiZoomEnabled(),
7066 mParameters.isStillMoreEnabled());
7067 pthread_mutex_unlock(&m_parm_lock);
7068 return true;
7069 }
7070
7071 pthread_mutex_unlock(&m_parm_lock);
7072 return false;
7073 }
7074
7075 /*===========================================================================
7076 * FUNCTION : needRotationReprocess
7077 *
7078 * DESCRIPTION: if rotation needs to be done by reprocess in pp
7079 *
7080 * PARAMETERS : none
7081 *
7082 * RETURN : true: needed
7083 * false: no need
7084 *==========================================================================*/
needRotationReprocess()7085 bool QCamera2HardwareInterface::needRotationReprocess()
7086 {
7087 pthread_mutex_lock(&m_parm_lock);
7088 if (!mParameters.isJpegPictureFormat() &&
7089 !mParameters.isNV21PictureFormat()) {
7090 // RAW image, no need to reprocess
7091 pthread_mutex_unlock(&m_parm_lock);
7092 return false;
7093 }
7094
7095 if (mParameters.is4k2kVideoResolution()&& mParameters.getRecordingHintValue()) {
7096 //Disable reprocess for 4K liveshot case
7097 pthread_mutex_unlock(&m_parm_lock);
7098 return false;
7099 }
7100
7101 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
7102 (mParameters.getJpegRotation() > 0)) {
7103 // current rotation is not zero, and pp has the capability to process rotation
7104 CDBG_HIGH("%s: need to do reprocess for rotation=%d",
7105 __func__, mParameters.getJpegRotation());
7106 pthread_mutex_unlock(&m_parm_lock);
7107 return true;
7108 }
7109
7110 pthread_mutex_unlock(&m_parm_lock);
7111 return false;
7112 }
7113
7114 /*===========================================================================
7115 * FUNCTION : needScaleReprocess
7116 *
7117 * DESCRIPTION: if scale needs to be done by reprocess in pp
7118 *
7119 * PARAMETERS : none
7120 *
7121 * RETURN : true: needed
7122 * false: no need
7123 *==========================================================================*/
needScaleReprocess()7124 bool QCamera2HardwareInterface::needScaleReprocess()
7125 {
7126 pthread_mutex_lock(&m_parm_lock);
7127 if (!mParameters.isJpegPictureFormat() &&
7128 !mParameters.isNV21PictureFormat()) {
7129 // RAW image, no need to reprocess
7130 pthread_mutex_unlock(&m_parm_lock);
7131 return false;
7132 }
7133
7134 if ((gCamCaps[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SCALE) > 0 &&
7135 mParameters.m_reprocScaleParam.isScaleEnabled() &&
7136 mParameters.m_reprocScaleParam.isUnderScaling()) {
7137 // Reproc Scale is enaled and also need Scaling to current Snapshot
7138 CDBG_HIGH("%s: need do reprocess for scale", __func__);
7139 pthread_mutex_unlock(&m_parm_lock);
7140 return true;
7141 }
7142
7143 pthread_mutex_unlock(&m_parm_lock);
7144 return false;
7145 }
7146
7147 /*===========================================================================
7148 * FUNCTION : getThumbnailSize
7149 *
7150 * DESCRIPTION: get user set thumbnail size
7151 *
7152 * PARAMETERS :
7153 * @dim : output of thumbnail dimension
7154 *
7155 * RETURN : none
7156 *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)7157 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
7158 {
7159 pthread_mutex_lock(&m_parm_lock);
7160 mParameters.getThumbnailSize(&dim.width, &dim.height);
7161 pthread_mutex_unlock(&m_parm_lock);
7162 }
7163
7164 /*===========================================================================
7165 * FUNCTION : getJpegQuality
7166 *
7167 * DESCRIPTION: get user set jpeg quality
7168 *
7169 * PARAMETERS : none
7170 *
7171 * RETURN : jpeg quality setting
7172 *==========================================================================*/
getJpegQuality()7173 uint32_t QCamera2HardwareInterface::getJpegQuality()
7174 {
7175 uint32_t quality = 0;
7176 pthread_mutex_lock(&m_parm_lock);
7177 quality = mParameters.getJpegQuality();
7178 pthread_mutex_unlock(&m_parm_lock);
7179 return quality;
7180 }
7181
7182 /*===========================================================================
7183 * FUNCTION : getExifData
7184 *
7185 * DESCRIPTION: get exif data to be passed into jpeg encoding
7186 *
7187 * PARAMETERS : none
7188 *
7189 * RETURN : exif data from user setting and GPS
7190 *==========================================================================*/
getExifData()7191 QCameraExif *QCamera2HardwareInterface::getExifData()
7192 {
7193 QCameraExif *exif = new QCameraExif();
7194 if (exif == NULL) {
7195 ALOGE("%s: No memory for QCameraExif", __func__);
7196 return NULL;
7197 }
7198
7199 int32_t rc = NO_ERROR;
7200
7201 pthread_mutex_lock(&m_parm_lock);
7202
7203 // add exif entries
7204 String8 dateTime, subSecTime;
7205 rc = mParameters.getExifDateTime(dateTime, subSecTime);
7206 if(rc == NO_ERROR) {
7207 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
7208 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
7209 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
7210 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
7211 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
7212 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
7213 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
7214 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
7215 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
7216 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
7217 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
7218 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
7219 } else {
7220 ALOGE("%s: getExifDateTime failed", __func__);
7221 }
7222
7223 rat_t focalLength;
7224 rc = mParameters.getExifFocalLength(&focalLength);
7225 if (rc == NO_ERROR) {
7226 exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
7227 EXIF_RATIONAL,
7228 1,
7229 (void *)&(focalLength));
7230 } else {
7231 ALOGE("%s: getExifFocalLength failed", __func__);
7232 }
7233
7234 uint16_t isoSpeed = mParameters.getExifIsoSpeed();
7235 if (getSensorType() != CAM_SENSOR_YUV) {
7236 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
7237 EXIF_SHORT,
7238 1,
7239 (void *)&(isoSpeed));
7240 }
7241
7242 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
7243 uint32_t count = 0;
7244 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
7245 if(rc == NO_ERROR) {
7246 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
7247 EXIF_ASCII,
7248 count,
7249 (void *)gpsProcessingMethod);
7250 } else {
7251 ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
7252 }
7253
7254 rat_t latitude[3];
7255 char latRef[2];
7256 rc = mParameters.getExifLatitude(latitude, latRef);
7257 if(rc == NO_ERROR) {
7258 exif->addEntry(EXIFTAGID_GPS_LATITUDE,
7259 EXIF_RATIONAL,
7260 3,
7261 (void *)latitude);
7262 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
7263 EXIF_ASCII,
7264 2,
7265 (void *)latRef);
7266 } else {
7267 ALOGE("%s: getExifLatitude failed", __func__);
7268 }
7269
7270 rat_t longitude[3];
7271 char lonRef[2];
7272 rc = mParameters.getExifLongitude(longitude, lonRef);
7273 if(rc == NO_ERROR) {
7274 exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
7275 EXIF_RATIONAL,
7276 3,
7277 (void *)longitude);
7278
7279 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
7280 EXIF_ASCII,
7281 2,
7282 (void *)lonRef);
7283 } else {
7284 ALOGE("%s: getExifLongitude failed", __func__);
7285 }
7286
7287 rat_t altitude;
7288 char altRef;
7289 rc = mParameters.getExifAltitude(&altitude, &altRef);
7290 if(rc == NO_ERROR) {
7291 exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
7292 EXIF_RATIONAL,
7293 1,
7294 (void *)&(altitude));
7295
7296 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
7297 EXIF_BYTE,
7298 1,
7299 (void *)&altRef);
7300 } else {
7301 ALOGE("%s: getExifAltitude failed", __func__);
7302 }
7303
7304 char gpsDateStamp[20];
7305 rat_t gpsTimeStamp[3];
7306 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
7307 if(rc == NO_ERROR) {
7308 exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
7309 EXIF_ASCII,
7310 (uint32_t)(strlen(gpsDateStamp) + 1),
7311 (void *)gpsDateStamp);
7312
7313 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
7314 EXIF_RATIONAL,
7315 3,
7316 (void *)gpsTimeStamp);
7317 } else {
7318 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
7319 }
7320
7321 #ifdef ENABLE_MODEL_INFO_EXIF
7322
7323 char value[PROPERTY_VALUE_MAX];
7324 if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
7325 exif->addEntry(EXIFTAGID_MAKE, EXIF_ASCII,
7326 (uint32_t)(strlen(value) + 1), (void *)value);
7327 } else {
7328 ALOGE("%s: getExifMaker failed", __func__);
7329 }
7330
7331 if (property_get("ro.product.model", value, "QCAM-AA") > 0) {
7332 exif->addEntry(EXIFTAGID_MODEL, EXIF_ASCII,
7333 (uint32_t)(strlen(value) + 1), (void *)value);
7334 } else {
7335 ALOGE("%s: getExifModel failed", __func__);
7336 }
7337
7338 if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
7339 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
7340 (uint32_t)(strlen(value) + 1), (void *)value);
7341 } else {
7342 ALOGE("%s: getExifSoftware failed", __func__);
7343 }
7344
7345 #endif
7346
7347 if (mParameters.useJpegExifRotation()) {
7348 int16_t orientation;
7349 switch (mParameters.getJpegExifRotation()) {
7350 case 0:
7351 orientation = 1;
7352 break;
7353 case 90:
7354 orientation = 6;
7355 break;
7356 case 180:
7357 orientation = 3;
7358 break;
7359 case 270:
7360 orientation = 8;
7361 break;
7362 default:
7363 orientation = 1;
7364 break;
7365 }
7366 exif->addEntry(EXIFTAGID_ORIENTATION,
7367 EXIF_SHORT,
7368 1,
7369 (void *)&orientation);
7370 exif->addEntry(EXIFTAGID_TN_ORIENTATION,
7371 EXIF_SHORT,
7372 1,
7373 (void *)&orientation);
7374 }
7375
7376 pthread_mutex_unlock(&m_parm_lock);
7377 return exif;
7378 }
7379
7380 /*===========================================================================
7381 * FUNCTION : setHistogram
7382 *
7383 * DESCRIPTION: set if histogram should be enabled
7384 *
7385 * PARAMETERS :
7386 * @histogram_en : bool flag if histogram should be enabled
7387 *
7388 * RETURN : int32_t type of status
7389 * NO_ERROR -- success
7390 * none-zero failure code
7391 *==========================================================================*/
setHistogram(bool histogram_en)7392 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
7393 {
7394 return mParameters.setHistogram(histogram_en);
7395 }
7396
7397 /*===========================================================================
7398 * FUNCTION : setFaceDetection
7399 *
7400 * DESCRIPTION: set if face detection should be enabled
7401 *
7402 * PARAMETERS :
7403 * @enabled : bool flag if face detection should be enabled
7404 *
7405 * RETURN : int32_t type of status
7406 * NO_ERROR -- success
7407 * none-zero failure code
7408 *==========================================================================*/
setFaceDetection(bool enabled)7409 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
7410 {
7411 return mParameters.setFaceDetection(enabled, true);
7412 }
7413
7414 /*===========================================================================
7415 * FUNCTION : isCaptureShutterEnabled
7416 *
7417 * DESCRIPTION: Check whether shutter should be triggered immediately after
7418 * capture
7419 *
7420 * PARAMETERS :
7421 *
7422 * RETURN : true - regular capture
7423 * false - other type of capture
7424 *==========================================================================*/
isCaptureShutterEnabled()7425 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
7426 {
7427 char prop[PROPERTY_VALUE_MAX];
7428 memset(prop, 0, sizeof(prop));
7429 property_get("persist.camera.feature.shutter", prop, "0");
7430 int enableShutter = atoi(prop);
7431 return enableShutter == 1;
7432 }
7433
7434 /*===========================================================================
7435 * FUNCTION : needProcessPreviewFrame
7436 *
7437 * DESCRIPTION: returns whether preview frame need to be displayed
7438 *
7439 * PARAMETERS :
7440 *
7441 * RETURN : int32_t type of status
7442 * NO_ERROR -- success
7443 * none-zero failure code
7444 *==========================================================================*/
needProcessPreviewFrame()7445 bool QCamera2HardwareInterface::needProcessPreviewFrame()
7446 {
7447 return m_stateMachine.isPreviewRunning()
7448 && mParameters.isDisplayFrameNeeded();
7449 };
7450
7451 /*===========================================================================
7452 * FUNCTION : prepareHardwareForSnapshot
7453 *
7454 * DESCRIPTION: prepare hardware for snapshot, such as LED
7455 *
7456 * PARAMETERS :
7457 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation
7458 *
7459 * RETURN : int32_t type of status
7460 * NO_ERROR -- success
7461 * none-zero failure code
7462 *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)7463 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
7464 {
7465 ATRACE_CALL();
7466 CDBG_HIGH("[KPI Perf] %s: Prepare hardware such as LED",__func__);
7467 return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
7468 afNeeded);
7469 }
7470
7471 /*===========================================================================
7472 * FUNCTION : needFDMetadata
7473 *
7474 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
7475 *
7476 * PARAMETERS :
7477 * @channel_type: channel type
7478 *
7479 * RETURN : true: needed
7480 * false: no need
7481 *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)7482 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
7483 {
7484 //Note: Currently we only process ZSL channel
7485 bool value = false;
7486 if(channel_type == QCAMERA_CH_TYPE_ZSL){
7487 //check if FD requirement is enabled
7488 if(mParameters.isSnapshotFDNeeded() &&
7489 mParameters.isFaceDetectionEnabled()){
7490 value = true;
7491 CDBG_HIGH("%s: Face Detection metadata is required in ZSL mode.", __func__);
7492 }
7493 }
7494
7495 return value;
7496 }
7497
7498 /*===========================================================================
7499 * FUNCTION : defferedWorkRoutine
7500 *
7501 * DESCRIPTION: data process routine that executes deffered tasks
7502 *
7503 * PARAMETERS :
7504 * @data : user data ptr (QCamera2HardwareInterface)
7505 *
7506 * RETURN : None
7507 *==========================================================================*/
defferedWorkRoutine(void * obj)7508 void *QCamera2HardwareInterface::defferedWorkRoutine(void *obj)
7509 {
7510 int running = 1;
7511 int ret;
7512 uint8_t is_active = FALSE;
7513
7514 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
7515 QCameraCmdThread *cmdThread = &pme->mDefferedWorkThread;
7516 cmdThread->setName("CAM_defrdWrk");
7517
7518 do {
7519 do {
7520 ret = cam_sem_wait(&cmdThread->cmd_sem);
7521 if (ret != 0 && errno != EINVAL) {
7522 ALOGE("%s: cam_sem_wait error (%s)",
7523 __func__, strerror(errno));
7524 return NULL;
7525 }
7526 } while (ret != 0);
7527
7528 // we got notified about new cmd avail in cmd queue
7529 camera_cmd_type_t cmd = cmdThread->getCmd();
7530 switch (cmd) {
7531 case CAMERA_CMD_TYPE_START_DATA_PROC:
7532 CDBG_HIGH("%s: start data proc", __func__);
7533 is_active = TRUE;
7534 break;
7535 case CAMERA_CMD_TYPE_STOP_DATA_PROC:
7536 CDBG_HIGH("%s: stop data proc", __func__);
7537 is_active = FALSE;
7538 // signal cmd is completed
7539 cam_sem_post(&cmdThread->sync_sem);
7540 break;
7541 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
7542 {
7543 DeffWork *dw =
7544 reinterpret_cast<DeffWork *>(pme->mCmdQueue.dequeue());
7545
7546 if ( NULL == dw ) {
7547 ALOGE("%s : Invalid deferred work", __func__);
7548 break;
7549 }
7550
7551 switch( dw->cmd ) {
7552 case CMD_DEFF_ALLOCATE_BUFF:
7553 {
7554 QCameraChannel * pChannel = dw->args.allocArgs.ch;
7555
7556 if ( NULL == pChannel ) {
7557 ALOGE("%s : Invalid deferred work channel",
7558 __func__);
7559 break;
7560 }
7561
7562 cam_stream_type_t streamType = dw->args.allocArgs.type;
7563 CDBG_HIGH("%s: Deffered buffer allocation started for stream type: %d",
7564 __func__, streamType);
7565
7566 uint32_t iNumOfStreams = pChannel->getNumOfStreams();
7567 QCameraStream *pStream = NULL;
7568 for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
7569 pStream = pChannel->getStreamByIndex(i);
7570
7571 if ( NULL == pStream ) {
7572 break;
7573 }
7574
7575 if ( pStream->isTypeOf(streamType)) {
7576 if ( pStream->allocateBuffers() ) {
7577 ALOGE("%s: Error allocating buffers !!!",
7578 __func__);
7579 }
7580 break;
7581 }
7582 }
7583 {
7584 Mutex::Autolock l(pme->mDeffLock);
7585 pme->mDeffOngoingJobs[dw->id] = false;
7586 CDBG_HIGH("%s: Deffered buffer allocation done for stream type: %d",
7587 __func__, streamType);
7588 delete dw;
7589 pme->mDeffCond.signal();
7590 }
7591
7592 }
7593 break;
7594 case CMD_DEFF_PPROC_START:
7595 {
7596 QCameraChannel * pChannel = dw->args.pprocArgs;
7597 assert(pChannel);
7598
7599 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
7600 ALOGE("%s: cannot start postprocessor", __func__);
7601 pme->delChannel(QCAMERA_CH_TYPE_CAPTURE);
7602 }
7603 {
7604 Mutex::Autolock l(pme->mDeffLock);
7605 pme->mDeffOngoingJobs[dw->id] = false;
7606 delete dw;
7607 pme->mDeffCond.broadcast();
7608 }
7609 }
7610 break;
7611 default:
7612 ALOGE("%s[%d]: Incorrect command : %d",
7613 __func__,
7614 __LINE__,
7615 dw->cmd);
7616 }
7617 }
7618 break;
7619 case CAMERA_CMD_TYPE_EXIT:
7620 running = 0;
7621 break;
7622 default:
7623 break;
7624 }
7625 } while (running);
7626
7627 return NULL;
7628 }
7629
7630 /*===========================================================================
7631 * FUNCTION : queueDefferedWork
7632 *
7633 * DESCRIPTION: function which queues deferred tasks
7634 *
7635 * PARAMETERS :
7636 * @cmd : deferred task
7637 * @args : deffered task arguments
7638 *
7639 * RETURN : int32_t type of status
7640 * NO_ERROR -- success
7641 * none-zero failure code
7642 *==========================================================================*/
queueDefferedWork(DefferedWorkCmd cmd,DefferWorkArgs args)7643 int32_t QCamera2HardwareInterface::queueDefferedWork(DefferedWorkCmd cmd,
7644 DefferWorkArgs args)
7645 {
7646 Mutex::Autolock l(mDeffLock);
7647 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
7648 if (!mDeffOngoingJobs[i]) {
7649 DeffWork *dw = new DeffWork(cmd, i, args);
7650 if (mCmdQueue.enqueue(dw)) {
7651 mDeffOngoingJobs[i] = true;
7652 mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
7653 FALSE,
7654 FALSE);
7655 return (int32_t)i;
7656 } else {
7657 CDBG("%s: Command queue not active! cmd = %d", __func__, cmd);
7658 delete dw;
7659 return -1;
7660 }
7661 }
7662 }
7663 return -1;
7664 }
7665
7666 /*===========================================================================
7667 * FUNCTION : waitDefferedWork
7668 *
7669 * DESCRIPTION: waits for a deffered task to finish
7670 *
7671 * PARAMETERS :
7672 * @job_id : deferred task id
7673 *
7674 * RETURN : int32_t type of status
7675 * NO_ERROR -- success
7676 * none-zero failure code
7677 *==========================================================================*/
waitDefferedWork(int32_t & job_id)7678 int32_t QCamera2HardwareInterface::waitDefferedWork(int32_t &job_id)
7679 {
7680 Mutex::Autolock l(mDeffLock);
7681
7682 if ((MAX_ONGOING_JOBS <= job_id) || (0 > job_id)) {
7683 return NO_ERROR;
7684 }
7685
7686 while ( mDeffOngoingJobs[job_id] == true ) {
7687 mDeffCond.wait(mDeffLock);
7688 }
7689
7690 return NO_ERROR;
7691 }
7692
7693 /*===========================================================================
7694 * FUNCTION : isRegularCapture
7695 *
7696 * DESCRIPTION: Check configuration for regular catpure
7697 *
7698 * PARAMETERS :
7699 *
7700 * RETURN : true - regular capture
7701 * false - other type of capture
7702 *==========================================================================*/
isRegularCapture()7703 bool QCamera2HardwareInterface::isRegularCapture()
7704 {
7705 bool ret = false;
7706
7707 if (numOfSnapshotsExpected() == 1 &&
7708 !isLongshotEnabled() &&
7709 !mParameters.isHDREnabled() &&
7710 !mParameters.getRecordingHintValue() &&
7711 !isZSLMode() && !mParameters.getofflineRAW()) {
7712 ret = true;
7713 }
7714 return ret;
7715 }
7716
7717 /*===========================================================================
7718 * FUNCTION : getLogLevel
7719 *
7720 * DESCRIPTION: Reads the log level property into a variable
7721 *
7722 * PARAMETERS :
7723 * None
7724 *
7725 * RETURN :
7726 * None
7727 *==========================================================================*/
getLogLevel()7728 void QCamera2HardwareInterface::getLogLevel()
7729 {
7730 char prop[PROPERTY_VALUE_MAX];
7731 uint32_t globalLogLevel = 0;
7732
7733 property_get("persist.camera.hal.debug", prop, "0");
7734 int val = atoi(prop);
7735 if (0 <= val) {
7736 gCamHalLogLevel = (uint32_t)val;
7737 }
7738 property_get("persist.camera.global.debug", prop, "0");
7739 val = atoi(prop);
7740 if (0 <= val) {
7741 globalLogLevel = (uint32_t)val;
7742 }
7743
7744 /* Highest log level among hal.logs and global.logs is selected */
7745 if (gCamHalLogLevel < globalLogLevel)
7746 gCamHalLogLevel = globalLogLevel;
7747
7748 return;
7749 }
7750
7751 /*===========================================================================
7752 * FUNCTION : getSensorType
7753 *
7754 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
7755 *
7756 * PARAMETERS :
7757 * None
7758 *
7759 * RETURN : Type of sensor - bayer or YUV
7760 *
7761 *==========================================================================*/
getSensorType()7762 cam_sensor_t QCamera2HardwareInterface::getSensorType()
7763 {
7764 return gCamCaps[mCameraId]->sensor_type.sens_type;
7765 }
7766
7767 }; // namespace qcamera
7768