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