1/* Copyright (c) 2012-2013, 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 <stdlib.h>
35#include <utils/Errors.h>
36#include <gralloc_priv.h>
37
38#include "QCamera2HWI.h"
39#include "QCameraMem.h"
40
41#define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) (val * scale / base + offset)
42#define CAMERA_MIN_STREAMING_BUFFERS     3
43#define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
44#define CAMERA_MIN_VIDEO_BUFFERS         9
45
46namespace qcamera {
47
48cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
49static pthread_mutex_t g_camlock = PTHREAD_MUTEX_INITIALIZER;
50
51camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
52    set_preview_window:         QCamera2HardwareInterface::set_preview_window,
53    set_callbacks:              QCamera2HardwareInterface::set_CallBacks,
54    enable_msg_type:            QCamera2HardwareInterface::enable_msg_type,
55    disable_msg_type:           QCamera2HardwareInterface::disable_msg_type,
56    msg_type_enabled:           QCamera2HardwareInterface::msg_type_enabled,
57
58    start_preview:              QCamera2HardwareInterface::start_preview,
59    stop_preview:               QCamera2HardwareInterface::stop_preview,
60    preview_enabled:            QCamera2HardwareInterface::preview_enabled,
61    store_meta_data_in_buffers: QCamera2HardwareInterface::store_meta_data_in_buffers,
62
63    start_recording:            QCamera2HardwareInterface::start_recording,
64    stop_recording:             QCamera2HardwareInterface::stop_recording,
65    recording_enabled:          QCamera2HardwareInterface::recording_enabled,
66    release_recording_frame:    QCamera2HardwareInterface::release_recording_frame,
67
68    auto_focus:                 QCamera2HardwareInterface::auto_focus,
69    cancel_auto_focus:          QCamera2HardwareInterface::cancel_auto_focus,
70
71    take_picture:               QCamera2HardwareInterface::take_picture,
72    cancel_picture:             QCamera2HardwareInterface::cancel_picture,
73
74    set_parameters:             QCamera2HardwareInterface::set_parameters,
75    get_parameters:             QCamera2HardwareInterface::get_parameters,
76    put_parameters:             QCamera2HardwareInterface::put_parameters,
77    send_command:               QCamera2HardwareInterface::send_command,
78
79    release:                    QCamera2HardwareInterface::release,
80    dump:                       QCamera2HardwareInterface::dump,
81};
82
83/*===========================================================================
84 * FUNCTION   : set_preview_window
85 *
86 * DESCRIPTION: set preview window.
87 *
88 * PARAMETERS :
89 *   @device  : ptr to camera device struct
90 *   @window  : window ops table
91 *
92 * RETURN     : int32_t type of status
93 *              NO_ERROR  -- success
94 *              none-zero failure code
95 *==========================================================================*/
96int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
97        struct preview_stream_ops *window)
98{
99    int rc = NO_ERROR;
100    QCamera2HardwareInterface *hw =
101        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
102    if (!hw) {
103        ALOGE("%s: NULL camera device", __func__);
104        return BAD_VALUE;
105    }
106
107    hw->lockAPI();
108    rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
109    if (rc == NO_ERROR) {
110        hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW);
111        rc = hw->m_apiResult.status;
112    }
113    hw->unlockAPI();
114
115    return rc;
116}
117
118/*===========================================================================
119 * FUNCTION   : set_CallBacks
120 *
121 * DESCRIPTION: set callbacks for notify and data
122 *
123 * PARAMETERS :
124 *   @device     : ptr to camera device struct
125 *   @notify_cb  : notify cb
126 *   @data_cb    : data cb
127 *   @data_cb_timestamp  : video data cd with timestamp
128 *   @get_memory : ops table for request gralloc memory
129 *   @user       : user data ptr
130 *
131 * RETURN     : none
132 *==========================================================================*/
133void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
134        camera_notify_callback notify_cb,
135        camera_data_callback data_cb,
136        camera_data_timestamp_callback data_cb_timestamp,
137        camera_request_memory get_memory,
138        void *user)
139{
140    QCamera2HardwareInterface *hw =
141        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
142    if (!hw) {
143        ALOGE("NULL camera device");
144        return;
145    }
146
147    qcamera_sm_evt_setcb_payload_t payload;
148    payload.notify_cb = notify_cb;
149    payload.data_cb = data_cb;
150    payload.data_cb_timestamp = data_cb_timestamp;
151    payload.get_memory = get_memory;
152    payload.user = user;
153
154    hw->lockAPI();
155    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
156    if (rc == NO_ERROR) {
157        hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS);
158    }
159    hw->unlockAPI();
160}
161
162/*===========================================================================
163 * FUNCTION   : enable_msg_type
164 *
165 * DESCRIPTION: enable certain msg type
166 *
167 * PARAMETERS :
168 *   @device     : ptr to camera device struct
169 *   @msg_type   : msg type mask
170 *
171 * RETURN     : none
172 *==========================================================================*/
173void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
174{
175    QCamera2HardwareInterface *hw =
176        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
177    if (!hw) {
178        ALOGE("NULL camera device");
179        return;
180    }
181    hw->lockAPI();
182    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)msg_type);
183    if (rc == NO_ERROR) {
184        hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE);
185    }
186    hw->unlockAPI();
187}
188
189/*===========================================================================
190 * FUNCTION   : disable_msg_type
191 *
192 * DESCRIPTION: disable certain msg type
193 *
194 * PARAMETERS :
195 *   @device     : ptr to camera device struct
196 *   @msg_type   : msg type mask
197 *
198 * RETURN     : none
199 *==========================================================================*/
200void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
201{
202    QCamera2HardwareInterface *hw =
203        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
204    if (!hw) {
205        ALOGE("NULL camera device");
206        return;
207    }
208    hw->lockAPI();
209    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)msg_type);
210    if (rc == NO_ERROR) {
211        hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE);
212    }
213    hw->unlockAPI();
214}
215
216/*===========================================================================
217 * FUNCTION   : msg_type_enabled
218 *
219 * DESCRIPTION: if certain msg type is enabled
220 *
221 * PARAMETERS :
222 *   @device     : ptr to camera device struct
223 *   @msg_type   : msg type mask
224 *
225 * RETURN     : 1 -- enabled
226 *              0 -- not enabled
227 *==========================================================================*/
228int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
229{
230    int ret = NO_ERROR;
231    QCamera2HardwareInterface *hw =
232        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
233    if (!hw) {
234        ALOGE("NULL camera device");
235        return BAD_VALUE;
236    }
237    hw->lockAPI();
238    ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)msg_type);
239    if (ret == NO_ERROR) {
240        hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED);
241        ret = hw->m_apiResult.enabled;
242    }
243    hw->unlockAPI();
244
245   return ret;
246}
247
248/*===========================================================================
249 * FUNCTION   : start_preview
250 *
251 * DESCRIPTION: start preview
252 *
253 * PARAMETERS :
254 *   @device  : ptr to camera device struct
255 *
256 * RETURN     : int32_t type of status
257 *              NO_ERROR  -- success
258 *              none-zero failure code
259 *==========================================================================*/
260int QCamera2HardwareInterface::start_preview(struct camera_device *device)
261{
262    int ret = NO_ERROR;
263    QCamera2HardwareInterface *hw =
264        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
265    if (!hw) {
266        ALOGE("NULL camera device");
267        return BAD_VALUE;
268    }
269    ALOGD("[KPI Perf] %s: E", __func__);
270    hw->lockAPI();
271    qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
272    if (hw->isNoDisplayMode()) {
273        evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
274    }
275    ret = hw->processAPI(evt, NULL);
276    if (ret == NO_ERROR) {
277        hw->waitAPIResult(evt);
278        ret = hw->m_apiResult.status;
279    }
280    hw->unlockAPI();
281    ALOGD("[KPI Perf] %s: X", __func__);
282    return ret;
283}
284
285/*===========================================================================
286 * FUNCTION   : stop_preview
287 *
288 * DESCRIPTION: stop preview
289 *
290 * PARAMETERS :
291 *   @device  : ptr to camera device struct
292 *
293 * RETURN     : none
294 *==========================================================================*/
295void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
296{
297    QCamera2HardwareInterface *hw =
298        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
299    if (!hw) {
300        ALOGE("NULL camera device");
301        return;
302    }
303    ALOGD("[KPI Perf] %s: E", __func__);
304    hw->lockAPI();
305    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
306    if (ret == NO_ERROR) {
307        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW);
308    }
309    hw->unlockAPI();
310    ALOGD("[KPI Perf] %s: X", __func__);
311}
312
313/*===========================================================================
314 * FUNCTION   : preview_enabled
315 *
316 * DESCRIPTION: if preview is running
317 *
318 * PARAMETERS :
319 *   @device  : ptr to camera device struct
320 *
321 * RETURN     : 1 -- running
322 *              0 -- not running
323 *==========================================================================*/
324int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
325{
326    int ret = NO_ERROR;
327    QCamera2HardwareInterface *hw =
328        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
329    if (!hw) {
330        ALOGE("NULL camera device");
331        return BAD_VALUE;
332    }
333
334    hw->lockAPI();
335    ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
336    if (ret == NO_ERROR) {
337        hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED);
338        ret = hw->m_apiResult.enabled;
339    }
340    hw->unlockAPI();
341
342    return ret;
343}
344
345/*===========================================================================
346 * FUNCTION   : store_meta_data_in_buffers
347 *
348 * DESCRIPTION: if need to store meta data in buffers for video frame
349 *
350 * PARAMETERS :
351 *   @device  : ptr to camera device struct
352 *   @enable  : flag if enable
353 *
354 * RETURN     : int32_t type of status
355 *              NO_ERROR  -- success
356 *              none-zero failure code
357 *==========================================================================*/
358int QCamera2HardwareInterface::store_meta_data_in_buffers(
359                struct camera_device *device, int enable)
360{
361    int ret = NO_ERROR;
362    QCamera2HardwareInterface *hw =
363        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
364    if (!hw) {
365        ALOGE("NULL camera device");
366        return BAD_VALUE;
367    }
368
369    hw->lockAPI();
370    ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)enable);
371    if (ret == NO_ERROR) {
372        hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS);
373        ret = hw->m_apiResult.status;
374    }
375    hw->unlockAPI();
376
377    return ret;
378}
379
380/*===========================================================================
381 * FUNCTION   : start_recording
382 *
383 * DESCRIPTION: start recording
384 *
385 * PARAMETERS :
386 *   @device  : ptr to camera device struct
387 *
388 * RETURN     : int32_t type of status
389 *              NO_ERROR  -- success
390 *              none-zero failure code
391 *==========================================================================*/
392int QCamera2HardwareInterface::start_recording(struct camera_device *device)
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    ALOGD("[KPI Perf] %s: E", __func__);
402    hw->lockAPI();
403    ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
404    if (ret == NO_ERROR) {
405        hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING);
406        ret = hw->m_apiResult.status;
407    }
408    hw->unlockAPI();
409    ALOGD("[KPI Perf] %s: X", __func__);
410    return ret;
411}
412
413/*===========================================================================
414 * FUNCTION   : stop_recording
415 *
416 * DESCRIPTION: stop recording
417 *
418 * PARAMETERS :
419 *   @device  : ptr to camera device struct
420 *
421 * RETURN     : none
422 *==========================================================================*/
423void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
424{
425    QCamera2HardwareInterface *hw =
426        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
427    if (!hw) {
428        ALOGE("NULL camera device");
429        return;
430    }
431    ALOGD("[KPI Perf] %s: E", __func__);
432    hw->lockAPI();
433    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
434    if (ret == NO_ERROR) {
435        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING);
436    }
437    hw->unlockAPI();
438    ALOGD("[KPI Perf] %s: X", __func__);
439}
440
441/*===========================================================================
442 * FUNCTION   : recording_enabled
443 *
444 * DESCRIPTION: if recording is running
445 *
446 * PARAMETERS :
447 *   @device  : ptr to camera device struct
448 *
449 * RETURN     : 1 -- running
450 *              0 -- not running
451 *==========================================================================*/
452int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
453{
454    int ret = NO_ERROR;
455    QCamera2HardwareInterface *hw =
456        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
457    if (!hw) {
458        ALOGE("NULL camera device");
459        return BAD_VALUE;
460    }
461    hw->lockAPI();
462    ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
463    if (ret == NO_ERROR) {
464        hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED);
465        ret = hw->m_apiResult.enabled;
466    }
467    hw->unlockAPI();
468
469    return ret;
470}
471
472/*===========================================================================
473 * FUNCTION   : release_recording_frame
474 *
475 * DESCRIPTION: return recording frame back
476 *
477 * PARAMETERS :
478 *   @device  : ptr to camera device struct
479 *   @opaque  : ptr to frame to be returned
480 *
481 * RETURN     : none
482 *==========================================================================*/
483void QCamera2HardwareInterface::release_recording_frame(
484            struct camera_device *device, const void *opaque)
485{
486    QCamera2HardwareInterface *hw =
487        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
488    if (!hw) {
489        ALOGE("NULL camera device");
490        return;
491    }
492    ALOGD("%s: E", __func__);
493    hw->lockAPI();
494    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
495    if (ret == NO_ERROR) {
496        hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME);
497    }
498    hw->unlockAPI();
499    ALOGD("%s: X", __func__);
500}
501
502/*===========================================================================
503 * FUNCTION   : auto_focus
504 *
505 * DESCRIPTION: start auto focus
506 *
507 * PARAMETERS :
508 *   @device  : ptr to camera device struct
509 *
510 * RETURN     : int32_t type of status
511 *              NO_ERROR  -- success
512 *              none-zero failure code
513 *==========================================================================*/
514int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
515{
516    int ret = NO_ERROR;
517    QCamera2HardwareInterface *hw =
518        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
519    if (!hw) {
520        ALOGE("NULL camera device");
521        return BAD_VALUE;
522    }
523    ALOGD("[KPI Perf] %s : E", __func__);
524    hw->lockAPI();
525    ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
526    if (ret == NO_ERROR) {
527        hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS);
528        ret = hw->m_apiResult.status;
529    }
530    hw->unlockAPI();
531    ALOGD("[KPI Perf] %s : X", __func__);
532
533    return ret;
534}
535
536/*===========================================================================
537 * FUNCTION   : cancel_auto_focus
538 *
539 * DESCRIPTION: cancel auto focus
540 *
541 * PARAMETERS :
542 *   @device  : ptr to camera device struct
543 *
544 * RETURN     : int32_t type of status
545 *              NO_ERROR  -- success
546 *              none-zero failure code
547 *==========================================================================*/
548int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
549{
550    int ret = NO_ERROR;
551    QCamera2HardwareInterface *hw =
552        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
553    if (!hw) {
554        ALOGE("NULL camera device");
555        return BAD_VALUE;
556    }
557    hw->lockAPI();
558    ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
559    if (ret == NO_ERROR) {
560        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS);
561        ret = hw->m_apiResult.status;
562    }
563    hw->unlockAPI();
564
565    return ret;
566}
567
568/*===========================================================================
569 * FUNCTION   : take_picture
570 *
571 * DESCRIPTION: take picture
572 *
573 * PARAMETERS :
574 *   @device  : ptr to camera device struct
575 *
576 * RETURN     : int32_t type of status
577 *              NO_ERROR  -- success
578 *              none-zero failure code
579 *==========================================================================*/
580int QCamera2HardwareInterface::take_picture(struct camera_device *device)
581{
582    int ret = NO_ERROR;
583    QCamera2HardwareInterface *hw =
584        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
585    if (!hw) {
586        ALOGE("NULL camera device");
587        return BAD_VALUE;
588    }
589    ALOGD("[KPI Perf] %s: E", __func__);
590    hw->lockAPI();
591
592    /* Prepare snapshot in case LED needs to be flashed */
593    ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
594    if (ret == NO_ERROR) {
595        hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT);
596        ret = hw->m_apiResult.status;
597    }
598
599    /* Regardless what the result value for prepare_snapshot,
600     * go ahead with capture anyway. Just like the way autofocus
601     * is handled in capture case. */
602
603    /* capture */
604    ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
605    if (ret == NO_ERROR) {
606        hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE);
607        ret = hw->m_apiResult.status;
608    }
609
610    hw->unlockAPI();
611    ALOGD("[KPI Perf] %s: X", __func__);
612    return ret;
613}
614
615/*===========================================================================
616 * FUNCTION   : cancel_picture
617 *
618 * DESCRIPTION: cancel current take picture request
619 *
620 * PARAMETERS :
621 *   @device  : ptr to camera device struct
622 *
623 * RETURN     : int32_t type of status
624 *              NO_ERROR  -- success
625 *              none-zero failure code
626 *==========================================================================*/
627int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
628{
629    int ret = NO_ERROR;
630    QCamera2HardwareInterface *hw =
631        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
632    if (!hw) {
633        ALOGE("NULL camera device");
634        return BAD_VALUE;
635    }
636    hw->lockAPI();
637    ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
638    if (ret == NO_ERROR) {
639        hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE);
640        ret = hw->m_apiResult.status;
641    }
642    hw->unlockAPI();
643
644    return ret;
645}
646
647/*===========================================================================
648 * FUNCTION   : set_parameters
649 *
650 * DESCRIPTION: set camera parameters
651 *
652 * PARAMETERS :
653 *   @device  : ptr to camera device struct
654 *   @parms   : string of packed parameters
655 *
656 * RETURN     : int32_t type of status
657 *              NO_ERROR  -- success
658 *              none-zero failure code
659 *==========================================================================*/
660int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
661                                              const char *parms)
662{
663    int ret = NO_ERROR;
664    QCamera2HardwareInterface *hw =
665        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
666    if (!hw) {
667        ALOGE("NULL camera device");
668        return BAD_VALUE;
669    }
670    hw->lockAPI();
671    ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
672    if (ret == NO_ERROR) {
673        hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS);
674        ret = hw->m_apiResult.status;
675    }
676    hw->unlockAPI();
677
678    return ret;
679}
680
681/*===========================================================================
682 * FUNCTION   : get_parameters
683 *
684 * DESCRIPTION: query camera parameters
685 *
686 * PARAMETERS :
687 *   @device  : ptr to camera device struct
688 *
689 * RETURN     : packed parameters in a string
690 *==========================================================================*/
691char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
692{
693    char *ret = NULL;
694    QCamera2HardwareInterface *hw =
695        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
696    if (!hw) {
697        ALOGE("NULL camera device");
698        return NULL;
699    }
700    hw->lockAPI();
701    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
702    if (rc == NO_ERROR) {
703        hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS);
704        ret = hw->m_apiResult.params;
705    }
706    hw->unlockAPI();
707
708    return ret;
709}
710
711/*===========================================================================
712 * FUNCTION   : put_parameters
713 *
714 * DESCRIPTION: return camera parameters string back to HAL
715 *
716 * PARAMETERS :
717 *   @device  : ptr to camera device struct
718 *   @parm    : ptr to parameter string to be returned
719 *
720 * RETURN     : none
721 *==========================================================================*/
722void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
723                                               char *parm)
724{
725    QCamera2HardwareInterface *hw =
726        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
727    if (!hw) {
728        ALOGE("NULL camera device");
729        return;
730    }
731    hw->lockAPI();
732    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
733    if (ret == NO_ERROR) {
734        hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS);
735    }
736    hw->unlockAPI();
737}
738
739/*===========================================================================
740 * FUNCTION   : send_command
741 *
742 * DESCRIPTION: command to be executed
743 *
744 * PARAMETERS :
745 *   @device  : ptr to camera device struct
746 *   @cmd     : cmd to be executed
747 *   @arg1    : ptr to optional argument1
748 *   @arg2    : ptr to optional argument2
749 *
750 * RETURN     : int32_t type of status
751 *              NO_ERROR  -- success
752 *              none-zero failure code
753 *==========================================================================*/
754int QCamera2HardwareInterface::send_command(struct camera_device *device,
755                                            int32_t cmd,
756                                            int32_t arg1,
757                                            int32_t arg2)
758{
759    int ret = NO_ERROR;
760    QCamera2HardwareInterface *hw =
761        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
762    if (!hw) {
763        ALOGE("NULL camera device");
764        return BAD_VALUE;
765    }
766
767    qcamera_sm_evt_command_payload_t payload;
768    memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
769    payload.cmd = cmd;
770    payload.arg1 = arg1;
771    payload.arg2 = arg2;
772    hw->lockAPI();
773    ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
774    if (ret == NO_ERROR) {
775        hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND);
776        ret = hw->m_apiResult.status;
777    }
778    hw->unlockAPI();
779
780    return ret;
781}
782
783/*===========================================================================
784 * FUNCTION   : release
785 *
786 * DESCRIPTION: release camera resource
787 *
788 * PARAMETERS :
789 *   @device  : ptr to camera device struct
790 *
791 * RETURN     : none
792 *==========================================================================*/
793void QCamera2HardwareInterface::release(struct camera_device *device)
794{
795    QCamera2HardwareInterface *hw =
796        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
797    if (!hw) {
798        ALOGE("NULL camera device");
799        return;
800    }
801    hw->lockAPI();
802    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
803    if (ret == NO_ERROR) {
804        hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE);
805    }
806    hw->unlockAPI();
807}
808
809/*===========================================================================
810 * FUNCTION   : dump
811 *
812 * DESCRIPTION: dump camera status
813 *
814 * PARAMETERS :
815 *   @device  : ptr to camera device struct
816 *   @fd      : fd for status to be dumped to
817 *
818 * RETURN     : int32_t type of status
819 *              NO_ERROR  -- success
820 *              none-zero failure code
821 *==========================================================================*/
822int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
823{
824    int ret = NO_ERROR;
825    QCamera2HardwareInterface *hw =
826        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
827    if (!hw) {
828        ALOGE("NULL camera device");
829        return BAD_VALUE;
830    }
831    hw->lockAPI();
832    ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)fd);
833    if (ret == NO_ERROR) {
834        hw->waitAPIResult(QCAMERA_SM_EVT_DUMP);
835        ret = hw->m_apiResult.status;
836    }
837    hw->unlockAPI();
838
839    return ret;
840}
841
842/*===========================================================================
843 * FUNCTION   : close_camera_device
844 *
845 * DESCRIPTION: close camera device
846 *
847 * PARAMETERS :
848 *   @device  : ptr to camera device struct
849 *
850 * RETURN     : int32_t type of status
851 *              NO_ERROR  -- success
852 *              none-zero failure code
853 *==========================================================================*/
854int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
855{
856    int ret = NO_ERROR;
857    ALOGD("[KPI Perf] %s: E",__func__);
858    QCamera2HardwareInterface *hw =
859        reinterpret_cast<QCamera2HardwareInterface *>(
860            reinterpret_cast<camera_device_t *>(hw_dev)->priv);
861    if (!hw) {
862        ALOGE("%s: NULL camera device", __func__);
863        return BAD_VALUE;
864    }
865    delete hw;
866    ALOGD("[KPI Perf] %s: X",__func__);
867    return ret;
868}
869
870/*===========================================================================
871 * FUNCTION   : register_face_image
872 *
873 * DESCRIPTION: register a face image into imaging lib for face authenticatio/
874 *              face recognition
875 *
876 * PARAMETERS :
877 *   @device  : ptr to camera device struct
878 *   @img_ptr : ptr to image buffer
879 *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
880 *
881 * RETURN     : >=0 unique ID of face registerd.
882 *              <0  failure.
883 *==========================================================================*/
884int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
885                                                   void *img_ptr,
886                                                   cam_pp_offline_src_config_t *config)
887{
888    int ret = NO_ERROR;
889    QCamera2HardwareInterface *hw =
890        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
891    if (!hw) {
892        ALOGE("NULL camera device");
893        return BAD_VALUE;
894    }
895    qcamera_sm_evt_reg_face_payload_t payload;
896    memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
897    payload.img_ptr = img_ptr;
898    payload.config = config;
899    hw->lockAPI();
900    ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
901    if (ret == NO_ERROR) {
902        hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE);
903        ret = hw->m_apiResult.handle;
904    }
905    hw->unlockAPI();
906
907    return ret;
908}
909
910/*===========================================================================
911 * FUNCTION   : QCamera2HardwareInterface
912 *
913 * DESCRIPTION: constructor of QCamera2HardwareInterface
914 *
915 * PARAMETERS :
916 *   @cameraId  : camera ID
917 *
918 * RETURN     : none
919 *==========================================================================*/
920QCamera2HardwareInterface::QCamera2HardwareInterface(int cameraId)
921    : mCameraId(cameraId),
922      mCameraHandle(NULL),
923      mCameraOpened(false),
924      mPreviewWindow(NULL),
925      mMsgEnabled(0),
926      mStoreMetaDataInFrame(0),
927      m_stateMachine(this),
928      m_postprocessor(this),
929      m_thermalAdapter(QCameraThermalAdapter::getInstance()),
930      m_cbNotifier(this),
931      m_bShutterSoundPlayed(false),
932      m_currentFocusState(CAM_AF_NOT_FOCUSED),
933      m_bStartZSLSnapshotCalled(false),
934      m_pPowerModule(NULL),
935      mDumpFrmCnt(0),
936      mDumpSkipCnt(0)
937{
938    mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
939    mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
940    mCameraDevice.common.close = close_camera_device;
941    mCameraDevice.ops = &mCameraOps;
942    mCameraDevice.priv = this;
943
944
945    pthread_mutex_init(&m_lock, NULL);
946    pthread_cond_init(&m_cond, NULL);
947    memset(&m_apiResult, 0, sizeof(qcamera_api_result_t));
948
949    pthread_mutex_init(&m_evtLock, NULL);
950    pthread_cond_init(&m_evtCond, NULL);
951    memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
952
953    memset(m_channels, 0, sizeof(m_channels));
954
955#ifdef HAS_MULTIMEDIA_HINTS
956    if (hw_get_module(POWER_HARDWARE_MODULE_ID, (const hw_module_t **)&m_pPowerModule)) {
957        ALOGE("%s: %s module not found", __func__, POWER_HARDWARE_MODULE_ID);
958    }
959#endif
960
961}
962
963/*===========================================================================
964 * FUNCTION   : ~QCamera2HardwareInterface
965 *
966 * DESCRIPTION: destructor of QCamera2HardwareInterface
967 *
968 * PARAMETERS : none
969 *
970 * RETURN     : none
971 *==========================================================================*/
972QCamera2HardwareInterface::~QCamera2HardwareInterface()
973{
974    closeCamera();
975    pthread_mutex_destroy(&m_lock);
976    pthread_cond_destroy(&m_cond);
977    pthread_mutex_destroy(&m_evtLock);
978    pthread_cond_destroy(&m_evtCond);
979}
980
981/*===========================================================================
982 * FUNCTION   : openCamera
983 *
984 * DESCRIPTION: open camera
985 *
986 * PARAMETERS :
987 *   @hw_device  : double ptr for camera device struct
988 *
989 * RETURN     : int32_t type of status
990 *              NO_ERROR  -- success
991 *              none-zero failure code
992 *==========================================================================*/
993int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
994{
995    int rc = NO_ERROR;
996    if (mCameraOpened) {
997        *hw_device = NULL;
998        return PERMISSION_DENIED;
999    }
1000
1001    rc = openCamera();
1002    if (rc == NO_ERROR)
1003        *hw_device = &mCameraDevice.common;
1004    else
1005        *hw_device = NULL;
1006    return rc;
1007}
1008
1009/*===========================================================================
1010 * FUNCTION   : openCamera
1011 *
1012 * DESCRIPTION: open camera
1013 *
1014 * PARAMETERS : none
1015 *
1016 * RETURN     : int32_t type of status
1017 *              NO_ERROR  -- success
1018 *              none-zero failure code
1019 *==========================================================================*/
1020int QCamera2HardwareInterface::openCamera()
1021{
1022    if (mCameraHandle) {
1023        ALOGE("Failure: Camera already opened");
1024        return ALREADY_EXISTS;
1025    }
1026    mCameraHandle = camera_open(mCameraId);
1027    if (!mCameraHandle) {
1028        ALOGE("camera_open failed.");
1029        return UNKNOWN_ERROR;
1030    }
1031
1032    mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1033                                              camEvtHandle,
1034                                              (void *) this);
1035
1036    int32_t rc = m_postprocessor.init(jpegEvtHandle, this);
1037    if (rc != 0) {
1038        ALOGE("Init Postprocessor failed");
1039        return UNKNOWN_ERROR;
1040    }
1041
1042    // update padding info from jpeg
1043    cam_padding_info_t padding_info;
1044    m_postprocessor.getJpegPaddingReq(padding_info);
1045    if (gCamCapability[mCameraId]->padding_info.width_padding < padding_info.width_padding) {
1046        gCamCapability[mCameraId]->padding_info.width_padding = padding_info.width_padding;
1047    }
1048    if (gCamCapability[mCameraId]->padding_info.height_padding < padding_info.height_padding) {
1049        gCamCapability[mCameraId]->padding_info.height_padding = padding_info.height_padding;
1050    }
1051    if (gCamCapability[mCameraId]->padding_info.plane_padding < padding_info.plane_padding) {
1052        gCamCapability[mCameraId]->padding_info.plane_padding = padding_info.plane_padding;
1053    }
1054
1055    mParameters.init(gCamCapability[mCameraId], mCameraHandle);
1056
1057    rc = m_thermalAdapter.init(this);
1058    if (rc != 0) {
1059        ALOGE("Init thermal adapter failed");
1060    }
1061
1062    mCameraOpened = true;
1063
1064    return NO_ERROR;
1065}
1066
1067/*===========================================================================
1068 * FUNCTION   : closeCamera
1069 *
1070 * DESCRIPTION: close camera
1071 *
1072 * PARAMETERS : none
1073 *
1074 * RETURN     : int32_t type of status
1075 *              NO_ERROR  -- success
1076 *              none-zero failure code
1077 *==========================================================================*/
1078int QCamera2HardwareInterface::closeCamera()
1079{
1080    int rc = NO_ERROR;
1081    int i;
1082
1083    // deinit Parameters
1084    mParameters.deinit();
1085
1086    // stop and deinit postprocessor
1087    m_postprocessor.stop();
1088    m_postprocessor.deinit();
1089
1090    m_thermalAdapter.deinit();
1091
1092    // delete all channels if not already deleted
1093    for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
1094        if (m_channels[i] != NULL) {
1095            m_channels[i]->stop();
1096            delete m_channels[i];
1097            m_channels[i] = NULL;
1098        }
1099    }
1100
1101    rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1102    mCameraHandle = NULL;
1103    mCameraOpened = false;
1104
1105    return rc;
1106}
1107
1108#define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
1109
1110/*===========================================================================
1111 * FUNCTION   : initCapabilities
1112 *
1113 * DESCRIPTION: initialize camera capabilities in static data struct
1114 *
1115 * PARAMETERS :
1116 *   @cameraId  : camera Id
1117 *
1118 * RETURN     : int32_t type of status
1119 *              NO_ERROR  -- success
1120 *              none-zero failure code
1121 *==========================================================================*/
1122int QCamera2HardwareInterface::initCapabilities(int cameraId)
1123{
1124    int rc = NO_ERROR;
1125    mm_camera_vtbl_t *cameraHandle = NULL;
1126    QCameraHeapMemory *capabilityHeap = NULL;
1127
1128    cameraHandle = camera_open(cameraId);
1129    if (!cameraHandle) {
1130        ALOGE("%s: camera_open failed", __func__);
1131        rc = UNKNOWN_ERROR;
1132        goto open_failed;
1133    }
1134
1135    /* Allocate memory for capability buffer */
1136    capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1137    rc = capabilityHeap->allocate(1, sizeof(cam_capability_t));
1138    if(rc != OK) {
1139        ALOGE("%s: No memory for cappability", __func__);
1140        goto allocate_failed;
1141    }
1142
1143    /* Map memory for capability buffer */
1144    memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
1145    rc = cameraHandle->ops->map_buf(cameraHandle->camera_handle,
1146                                CAM_MAPPING_BUF_TYPE_CAPABILITY,
1147                                capabilityHeap->getFd(0),
1148                                sizeof(cam_capability_t));
1149    if(rc < 0) {
1150        ALOGE("%s: failed to map capability buffer", __func__);
1151        goto map_failed;
1152    }
1153
1154    /* Query Capability */
1155    rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
1156    if(rc < 0) {
1157        ALOGE("%s: failed to query capability",__func__);
1158        goto query_failed;
1159    }
1160    gCamCapability[cameraId] = (cam_capability_t *)malloc(sizeof(cam_capability_t));
1161    if (!gCamCapability[cameraId]) {
1162        ALOGE("%s: out of memory", __func__);
1163        goto query_failed;
1164    }
1165    memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),
1166                                        sizeof(cam_capability_t));
1167
1168    rc = NO_ERROR;
1169
1170query_failed:
1171    cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
1172                            CAM_MAPPING_BUF_TYPE_CAPABILITY);
1173map_failed:
1174    capabilityHeap->deallocate();
1175    delete capabilityHeap;
1176allocate_failed:
1177    cameraHandle->ops->close_camera(cameraHandle->camera_handle);
1178    cameraHandle = NULL;
1179open_failed:
1180    return rc;
1181}
1182
1183/*===========================================================================
1184 * FUNCTION   : getCapabilities
1185 *
1186 * DESCRIPTION: query camera capabilities
1187 *
1188 * PARAMETERS :
1189 *   @cameraId  : camera Id
1190 *   @info      : camera info struct to be filled in with camera capabilities
1191 *
1192 * RETURN     : int32_t type of status
1193 *              NO_ERROR  -- success
1194 *              none-zero failure code
1195 *==========================================================================*/
1196int QCamera2HardwareInterface::getCapabilities(int cameraId,
1197                                    struct camera_info *info)
1198{
1199    int rc = NO_ERROR;
1200
1201    pthread_mutex_lock(&g_camlock);
1202    if (NULL == gCamCapability[cameraId]) {
1203        rc = initCapabilities(cameraId);
1204        if (rc < 0) {
1205            pthread_mutex_unlock(&g_camlock);
1206            return rc;
1207        }
1208    }
1209
1210    switch(gCamCapability[cameraId]->position) {
1211    case CAM_POSITION_BACK:
1212        info->facing = CAMERA_FACING_BACK;
1213        break;
1214
1215    case CAM_POSITION_FRONT:
1216        info->facing = CAMERA_FACING_FRONT;
1217        break;
1218
1219    default:
1220        ALOGE("%s:Unknown position type for camera id:%d", __func__, cameraId);
1221        rc = BAD_VALUE;
1222        break;
1223    }
1224
1225    info->orientation = gCamCapability[cameraId]->sensor_mount_angle;
1226    pthread_mutex_unlock(&g_camlock);
1227    return rc;
1228}
1229
1230/*===========================================================================
1231 * FUNCTION   : getBufNumRequired
1232 *
1233 * DESCRIPTION: return number of stream buffers needed for given stream type
1234 *
1235 * PARAMETERS :
1236 *   @stream_type  : type of stream
1237 *
1238 * RETURN     : number of buffers needed
1239 *==========================================================================*/
1240uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
1241{
1242    int bufferCnt = 0;
1243    int minCaptureBuffers = mParameters.getNumOfSnapshots();
1244
1245    int zslQBuffers = mParameters.getZSLQueueDepth() +
1246                      mParameters.getMaxUnmatchedFramesInQueue();
1247
1248    int minCircularBufNum = CAMERA_MIN_STREAMING_BUFFERS +
1249                            CAMERA_MIN_JPEG_ENCODING_BUFFERS +
1250                            mParameters.getMaxUnmatchedFramesInQueue() +
1251                            mParameters.getNumOfHDRBufsIfNeeded();
1252
1253    // Get buffer count for the particular stream type
1254    switch (stream_type) {
1255    case CAM_STREAM_TYPE_PREVIEW:
1256        {
1257            if (mParameters.isZSLMode()) {
1258                bufferCnt = zslQBuffers + minCircularBufNum;
1259            } else {
1260                bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
1261                            mParameters.getMaxUnmatchedFramesInQueue();
1262            }
1263        }
1264        break;
1265    case CAM_STREAM_TYPE_POSTVIEW:
1266        {
1267            bufferCnt = minCaptureBuffers +
1268                        mParameters.getMaxUnmatchedFramesInQueue() +
1269                        mParameters.getNumOfExtraHDRBufsIfNeeded() +
1270                        CAMERA_MIN_STREAMING_BUFFERS;
1271        }
1272        break;
1273    case CAM_STREAM_TYPE_SNAPSHOT:
1274    case CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT:
1275        {
1276            if (mParameters.isZSLMode()) {
1277                bufferCnt = zslQBuffers + minCircularBufNum;
1278            } else {
1279                bufferCnt = minCaptureBuffers +
1280                            mParameters.getMaxUnmatchedFramesInQueue() +
1281                            mParameters.getNumOfExtraHDRBufsIfNeeded() +
1282                            CAMERA_MIN_STREAMING_BUFFERS;
1283            }
1284        }
1285        break;
1286    case CAM_STREAM_TYPE_RAW:
1287        if (mParameters.isZSLMode()) {
1288            bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS;
1289        } else {
1290            bufferCnt = minCaptureBuffers +
1291                        mParameters.getMaxUnmatchedFramesInQueue() +
1292                        mParameters.getNumOfExtraHDRBufsIfNeeded() +
1293                        CAMERA_MIN_STREAMING_BUFFERS;
1294        }
1295        break;
1296    case CAM_STREAM_TYPE_VIDEO:
1297        {
1298            bufferCnt = CAMERA_MIN_VIDEO_BUFFERS +
1299                        mParameters.getMaxUnmatchedFramesInQueue() +
1300                        CAMERA_MIN_STREAMING_BUFFERS;
1301        }
1302        break;
1303    case CAM_STREAM_TYPE_METADATA:
1304        {
1305            bufferCnt = minCaptureBuffers +
1306                        mParameters.getMaxUnmatchedFramesInQueue() +
1307                        mParameters.getNumOfExtraHDRBufsIfNeeded() +
1308                        CAMERA_MIN_STREAMING_BUFFERS;
1309            if (bufferCnt < zslQBuffers + minCircularBufNum) {
1310                bufferCnt = zslQBuffers + minCircularBufNum;
1311            }
1312        }
1313        break;
1314    case CAM_STREAM_TYPE_OFFLINE_PROC:
1315        {
1316            bufferCnt = minCaptureBuffers +
1317                        mParameters.getMaxUnmatchedFramesInQueue();
1318            if (bufferCnt < CAMERA_MIN_STREAMING_BUFFERS) {
1319                bufferCnt = CAMERA_MIN_STREAMING_BUFFERS;
1320            }
1321        }
1322        break;
1323    case CAM_STREAM_TYPE_DEFAULT:
1324    case CAM_STREAM_TYPE_MAX:
1325    default:
1326        bufferCnt = 0;
1327        break;
1328    }
1329
1330    return bufferCnt;
1331}
1332
1333/*===========================================================================
1334 * FUNCTION   : allocateStreamBuf
1335 *
1336 * DESCRIPTION: alocate stream buffers
1337 *
1338 * PARAMETERS :
1339 *   @stream_type  : type of stream
1340 *   @size         : size of buffer
1341 *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
1342 *                   could be modified during allocation if more buffers needed
1343 *
1344 * RETURN     : ptr to a memory obj that holds stream buffers.
1345 *              NULL if failed
1346 *==========================================================================*/
1347QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(cam_stream_type_t stream_type,
1348                                                            int size,
1349                                                            uint8_t &bufferCnt)
1350{
1351    int rc = NO_ERROR;
1352    QCameraMemory *mem = NULL;
1353    bool bCachedMem = QCAMERA_ION_USE_CACHE;
1354
1355    // Allocate stream buffer memory object
1356    switch (stream_type) {
1357    case CAM_STREAM_TYPE_PREVIEW:
1358        {
1359            if (isNoDisplayMode()) {
1360                mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
1361            } else {
1362                cam_dimension_t dim;
1363                QCameraGrallocMemory *grallocMemory =
1364                    new QCameraGrallocMemory(mGetMemory);
1365
1366                mParameters.getStreamDimension(stream_type, dim);
1367                if (grallocMemory)
1368                    grallocMemory->setWindowInfo(mPreviewWindow, dim.width, dim.height,
1369                            mParameters.getPreviewHalPixelFormat());
1370                mem = grallocMemory;
1371            }
1372        }
1373        break;
1374    case CAM_STREAM_TYPE_POSTVIEW:
1375        {
1376            cam_dimension_t dim;
1377            QCameraGrallocMemory *grallocMemory =
1378                new QCameraGrallocMemory(mGetMemory);
1379
1380            mParameters.getStreamDimension(stream_type, dim);
1381            if (grallocMemory)
1382                grallocMemory->setWindowInfo(mPreviewWindow, dim.width, dim.height,
1383                        mParameters.getPreviewHalPixelFormat());
1384            mem = grallocMemory;
1385        }
1386        break;
1387    case CAM_STREAM_TYPE_SNAPSHOT:
1388    case CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT:
1389    case CAM_STREAM_TYPE_RAW:
1390    case CAM_STREAM_TYPE_METADATA:
1391    case CAM_STREAM_TYPE_OFFLINE_PROC:
1392        mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
1393        break;
1394    case CAM_STREAM_TYPE_VIDEO:
1395        {
1396            char value[PROPERTY_VALUE_MAX];
1397            property_get("persist.camera.mem.usecache", value, "1");
1398            if (atoi(value) == 0) {
1399                bCachedMem = QCAMERA_ION_USE_NOCACHE;
1400            }
1401            ALOGD("%s: vidoe buf using cached memory = %d", __func__, bCachedMem);
1402            mem = new QCameraVideoMemory(mGetMemory, bCachedMem);
1403        }
1404        break;
1405    case CAM_STREAM_TYPE_DEFAULT:
1406    case CAM_STREAM_TYPE_MAX:
1407    default:
1408        break;
1409    }
1410    if (!mem) {
1411        return NULL;
1412    }
1413
1414    if (bufferCnt > 0) {
1415        rc = mem->allocate(bufferCnt, size);
1416        if (rc < 0) {
1417            delete mem;
1418            return NULL;
1419        }
1420        bufferCnt = mem->getCnt();
1421    }
1422    return mem;
1423}
1424
1425/*===========================================================================
1426 * FUNCTION   : allocateStreamInfoBuf
1427 *
1428 * DESCRIPTION: alocate stream info buffer
1429 *
1430 * PARAMETERS :
1431 *   @stream_type  : type of stream
1432 *
1433 * RETURN     : ptr to a memory obj that holds stream info buffer.
1434 *              NULL if failed
1435 *==========================================================================*/
1436QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
1437    cam_stream_type_t stream_type)
1438{
1439    int rc = NO_ERROR;
1440
1441    QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
1442    if (!streamInfoBuf) {
1443        ALOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
1444        return NULL;
1445    }
1446
1447    rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t));
1448    if (rc < 0) {
1449        ALOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
1450        delete streamInfoBuf;
1451        return NULL;
1452    }
1453
1454    cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
1455    memset(streamInfo, 0, sizeof(cam_stream_info_t));
1456    streamInfo->stream_type = stream_type;
1457    rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
1458    rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
1459
1460    streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1461    switch (stream_type) {
1462    case CAM_STREAM_TYPE_SNAPSHOT:
1463    case CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT:
1464    case CAM_STREAM_TYPE_RAW:
1465        if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
1466            streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1467        } else {
1468            streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1469            streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
1470        }
1471        break;
1472    case CAM_STREAM_TYPE_POSTVIEW:
1473        streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1474        streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
1475        break;
1476    default:
1477        break;
1478    }
1479
1480    //set flip mode based on Stream type;
1481    int flipMode = mParameters.getFlipMode(stream_type);
1482    if (flipMode > 0) {
1483        streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_FLIP;
1484        streamInfo->pp_config.flip = flipMode;
1485    }
1486
1487    return streamInfoBuf;
1488}
1489
1490/*===========================================================================
1491 * FUNCTION   : setPreviewWindow
1492 *
1493 * DESCRIPTION: set preview window impl
1494 *
1495 * PARAMETERS :
1496 *   @window  : ptr to window ops table struct
1497 *
1498 * RETURN     : int32_t type of status
1499 *              NO_ERROR  -- success
1500 *              none-zero failure code
1501 *==========================================================================*/
1502int QCamera2HardwareInterface::setPreviewWindow(
1503        struct preview_stream_ops *window)
1504{
1505    mPreviewWindow = window;
1506    return NO_ERROR;
1507}
1508
1509/*===========================================================================
1510 * FUNCTION   : setCallBacks
1511 *
1512 * DESCRIPTION: set callbacks impl
1513 *
1514 * PARAMETERS :
1515 *   @notify_cb  : notify cb
1516 *   @data_cb    : data cb
1517 *   @data_cb_timestamp : data cb with time stamp
1518 *   @get_memory : request memory ops table
1519 *   @user       : user data ptr
1520 *
1521 * RETURN     : int32_t type of status
1522 *              NO_ERROR  -- success
1523 *              none-zero failure code
1524 *==========================================================================*/
1525int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
1526                                            camera_data_callback data_cb,
1527                                            camera_data_timestamp_callback data_cb_timestamp,
1528                                            camera_request_memory get_memory,
1529                                            void *user)
1530{
1531    mNotifyCb        = notify_cb;
1532    mDataCb          = data_cb;
1533    mDataCbTimestamp = data_cb_timestamp;
1534    mGetMemory       = get_memory;
1535    mCallbackCookie  = user;
1536    m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
1537    return NO_ERROR;
1538}
1539
1540/*===========================================================================
1541 * FUNCTION   : enableMsgType
1542 *
1543 * DESCRIPTION: enable msg type impl
1544 *
1545 * PARAMETERS :
1546 *   @msg_type  : msg type mask to be enabled
1547 *
1548 * RETURN     : int32_t type of status
1549 *              NO_ERROR  -- success
1550 *              none-zero failure code
1551 *==========================================================================*/
1552int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
1553{
1554    mMsgEnabled |= msg_type;
1555    return NO_ERROR;
1556}
1557
1558/*===========================================================================
1559 * FUNCTION   : disableMsgType
1560 *
1561 * DESCRIPTION: disable msg type impl
1562 *
1563 * PARAMETERS :
1564 *   @msg_type  : msg type mask to be disabled
1565 *
1566 * RETURN     : int32_t type of status
1567 *              NO_ERROR  -- success
1568 *              none-zero failure code
1569 *==========================================================================*/
1570int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
1571{
1572    mMsgEnabled &= ~msg_type;
1573    return NO_ERROR;
1574}
1575
1576/*===========================================================================
1577 * FUNCTION   : msgTypeEnabled
1578 *
1579 * DESCRIPTION: impl to determine if certain msg_type is enabled
1580 *
1581 * PARAMETERS :
1582 *   @msg_type  : msg type mask
1583 *
1584 * RETURN     : 0 -- not enabled
1585 *              none 0 -- enabled
1586 *==========================================================================*/
1587int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
1588{
1589    return (mMsgEnabled & msg_type);
1590}
1591
1592/*===========================================================================
1593 * FUNCTION   : msgTypeEnabledWithLock
1594 *
1595 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
1596 *
1597 * PARAMETERS :
1598 *   @msg_type  : msg type mask
1599 *
1600 * RETURN     : 0 -- not enabled
1601 *              none 0 -- enabled
1602 *==========================================================================*/
1603int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
1604{
1605    int enabled = 0;
1606    lockAPI();
1607    enabled = mMsgEnabled & msg_type;
1608    unlockAPI();
1609    return enabled;
1610}
1611
1612/*===========================================================================
1613 * FUNCTION   : startPreview
1614 *
1615 * DESCRIPTION: start preview impl
1616 *
1617 * PARAMETERS : none
1618 *
1619 * RETURN     : int32_t type of status
1620 *              NO_ERROR  -- success
1621 *              none-zero failure code
1622 *==========================================================================*/
1623int QCamera2HardwareInterface::startPreview()
1624{
1625    int32_t rc = NO_ERROR;
1626    ALOGD("%s: E", __func__);
1627    // start preview stream
1628    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
1629        rc = startChannel(QCAMERA_CH_TYPE_ZSL);
1630    } else {
1631        rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
1632    }
1633    ALOGD("%s: X", __func__);
1634    return rc;
1635}
1636
1637/*===========================================================================
1638 * FUNCTION   : stopPreview
1639 *
1640 * DESCRIPTION: stop preview impl
1641 *
1642 * PARAMETERS : none
1643 *
1644 * RETURN     : int32_t type of status
1645 *              NO_ERROR  -- success
1646 *              none-zero failure code
1647 *==========================================================================*/
1648int QCamera2HardwareInterface::stopPreview()
1649{
1650    ALOGD("%s: E", __func__);
1651    // stop preview stream
1652    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
1653        stopChannel(QCAMERA_CH_TYPE_ZSL);
1654    } else {
1655        stopChannel(QCAMERA_CH_TYPE_PREVIEW);
1656    }
1657
1658    // delete all channels from preparePreview
1659    unpreparePreview();
1660    ALOGD("%s: X", __func__);
1661    return NO_ERROR;
1662}
1663
1664/*===========================================================================
1665 * FUNCTION   : storeMetaDataInBuffers
1666 *
1667 * DESCRIPTION: enable store meta data in buffers for video frames impl
1668 *
1669 * PARAMETERS :
1670 *   @enable  : flag if need enable
1671 *
1672 * RETURN     : int32_t type of status
1673 *              NO_ERROR  -- success
1674 *              none-zero failure code
1675 *==========================================================================*/
1676int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
1677{
1678    mStoreMetaDataInFrame = enable;
1679    return NO_ERROR;
1680}
1681
1682/*===========================================================================
1683 * FUNCTION   : startRecording
1684 *
1685 * DESCRIPTION: start recording impl
1686 *
1687 * PARAMETERS : none
1688 *
1689 * RETURN     : int32_t type of status
1690 *              NO_ERROR  -- success
1691 *              none-zero failure code
1692 *==========================================================================*/
1693int QCamera2HardwareInterface::startRecording()
1694{
1695    int32_t rc = NO_ERROR;
1696    ALOGD("%s: E", __func__);
1697    if (mParameters.getRecordingHintValue() == false) {
1698        ALOGE("%s: start recording when hint is false, stop preview first", __func__);
1699        stopChannel(QCAMERA_CH_TYPE_PREVIEW);
1700        delChannel(QCAMERA_CH_TYPE_PREVIEW);
1701
1702        // Set recording hint to TRUE
1703        mParameters.updateRecordingHintValue(TRUE);
1704        rc = preparePreview();
1705        if (rc == NO_ERROR) {
1706            rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
1707        }
1708    }
1709
1710    if (rc == NO_ERROR) {
1711        rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
1712    }
1713
1714#ifdef HAS_MULTIMEDIA_HINTS
1715    if (rc == NO_ERROR) {
1716        if (m_pPowerModule) {
1717            if (m_pPowerModule->powerHint) {
1718                m_pPowerModule->powerHint(m_pPowerModule, POWER_HINT_VIDEO_ENCODE, (void *)"state=1");
1719            }
1720        }
1721    }
1722#endif
1723    ALOGD("%s: X", __func__);
1724    return rc;
1725}
1726
1727/*===========================================================================
1728 * FUNCTION   : stopRecording
1729 *
1730 * DESCRIPTION: stop recording impl
1731 *
1732 * PARAMETERS : none
1733 *
1734 * RETURN     : int32_t type of status
1735 *              NO_ERROR  -- success
1736 *              none-zero failure code
1737 *==========================================================================*/
1738int QCamera2HardwareInterface::stopRecording()
1739{
1740    int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
1741    ALOGD("%s: E", __func__);
1742#ifdef HAS_MULTIMEDIA_HINTS
1743    if (m_pPowerModule) {
1744        if (m_pPowerModule->powerHint) {
1745            m_pPowerModule->powerHint(m_pPowerModule, POWER_HINT_VIDEO_ENCODE, (void *)"state=0");
1746        }
1747    }
1748#endif
1749    ALOGD("%s: X", __func__);
1750    return rc;
1751}
1752
1753/*===========================================================================
1754 * FUNCTION   : releaseRecordingFrame
1755 *
1756 * DESCRIPTION: return video frame impl
1757 *
1758 * PARAMETERS :
1759 *   @opaque  : ptr to video frame to be returned
1760 *
1761 * RETURN     : int32_t type of status
1762 *              NO_ERROR  -- success
1763 *              none-zero failure code
1764 *==========================================================================*/
1765int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
1766{
1767    int32_t rc = UNKNOWN_ERROR;
1768    QCameraVideoChannel *pChannel =
1769        (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
1770    ALOGD("%s: opaque data = %p", __func__,opaque);
1771    if(pChannel != NULL) {
1772        rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
1773    }
1774    return rc;
1775}
1776
1777/*===========================================================================
1778 * FUNCTION   : autoFocus
1779 *
1780 * DESCRIPTION: start auto focus impl
1781 *
1782 * PARAMETERS : none
1783 *
1784 * RETURN     : int32_t type of status
1785 *              NO_ERROR  -- success
1786 *              none-zero failure code
1787 *==========================================================================*/
1788int QCamera2HardwareInterface::autoFocus()
1789{
1790    int rc = NO_ERROR;
1791    cam_focus_mode_type focusMode = mParameters.getFocusMode();
1792
1793    switch (focusMode) {
1794    case CAM_FOCUS_MODE_AUTO:
1795    case CAM_FOCUS_MODE_MACRO:
1796        {
1797            rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
1798            if (rc == NO_ERROR) {
1799                mParameters.setAFRunning(true);
1800            }
1801        }
1802        break;
1803    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
1804        // According to Google API definition, the focus callback will immediately
1805        // return with a boolean that indicates whether the focus is sharp or not.
1806        // The focus position is locked after autoFocus call.
1807        // in this sense, the effect is the same as cancel_auto_focus
1808        {
1809            rc = mParameters.setLockCAF(true);
1810
1811            // send evt notify that foucs is done
1812            sendEvtNotify(CAMERA_MSG_FOCUS,
1813                          (m_currentFocusState == CAM_AF_FOCUSED)? true : false,
1814                          0);
1815        }
1816        break;
1817    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
1818        // According to Google API definition, if the autofocus is in the middle
1819        // of scanning, the focus callback will return when it completes. If the
1820        // autofocus is not scanning, focus callback will immediately return with
1821        // a boolean that indicates whether the focus is sharp or not. The apps
1822        // can then decide if they want to take a picture immediately or to change
1823        // the focus mode to auto, and run a full autofocus cycle. The focus position
1824        // is locked after autoFocus call.
1825        if (m_currentFocusState != CAM_AF_SCANNING) {
1826            // lock focus
1827            rc = mParameters.setLockCAF(true);
1828
1829            // send evt notify that foucs is done
1830            sendEvtNotify(CAMERA_MSG_FOCUS,
1831                          (m_currentFocusState == CAM_AF_FOCUSED)? true : false,
1832                          0);
1833        } else {
1834            // set flag that lock CAF is needed once focus state becomes focsued/not focused
1835            mParameters.setLockCAFNeeded(true);
1836            rc = NO_ERROR;
1837        }
1838        break;
1839    case CAM_FOCUS_MODE_INFINITY:
1840    case CAM_FOCUS_MODE_FIXED:
1841    case CAM_FOCUS_MODE_EDOF:
1842    default:
1843        ALOGE("%s: No ops in focusMode (%d)", __func__, focusMode);
1844        rc = BAD_VALUE;
1845        break;
1846    }
1847    return rc;
1848}
1849
1850/*===========================================================================
1851 * FUNCTION   : cancelAutoFocus
1852 *
1853 * DESCRIPTION: cancel auto focus impl
1854 *
1855 * PARAMETERS : none
1856 *
1857 * RETURN     : int32_t type of status
1858 *              NO_ERROR  -- success
1859 *              none-zero failure code
1860 *==========================================================================*/
1861int QCamera2HardwareInterface::cancelAutoFocus()
1862{
1863    int rc = NO_ERROR;
1864    cam_focus_mode_type focusMode = mParameters.getFocusMode();
1865
1866    switch (focusMode) {
1867    case CAM_FOCUS_MODE_AUTO:
1868    case CAM_FOCUS_MODE_MACRO:
1869        if (mParameters.isAFRunning()) {
1870            rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
1871            if (rc == NO_ERROR) {
1872                mParameters.setAFRunning(false);
1873            }
1874        }
1875        break;
1876    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
1877    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
1878        if (mParameters.isCAFLocked()) {
1879            // resume CAF by unlock CAF
1880            rc = mParameters.setLockCAF(false);;
1881            mParameters.setLockCAFNeeded(false);
1882        }
1883        break;
1884    case CAM_FOCUS_MODE_INFINITY:
1885    case CAM_FOCUS_MODE_FIXED:
1886    case CAM_FOCUS_MODE_EDOF:
1887    default:
1888        ALOGI("%s: No ops in focusMode (%d)", __func__, focusMode);
1889        break;
1890    }
1891    return rc;
1892}
1893
1894/*===========================================================================
1895 * FUNCTION   : takePicture
1896 *
1897 * DESCRIPTION: take picture impl
1898 *
1899 * PARAMETERS : none
1900 *
1901 * RETURN     : int32_t type of status
1902 *              NO_ERROR  -- success
1903 *              none-zero failure code
1904 *==========================================================================*/
1905int QCamera2HardwareInterface::takePicture()
1906{
1907    int rc = NO_ERROR;
1908    uint8_t numSnapshots = mParameters.getNumOfSnapshots();
1909    ALOGD("%s: E", __func__);
1910    if (mParameters.isZSLMode()) {
1911        QCameraPicChannel *pZSLChannel =
1912            (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
1913        if (NULL != pZSLChannel) {
1914            // start postprocessor
1915            m_postprocessor.start(pZSLChannel);
1916
1917            rc = pZSLChannel->takePicture(numSnapshots);
1918            if (rc != NO_ERROR) {
1919                ALOGE("%s: cannot take ZSL picture", __func__);
1920                m_postprocessor.stop();
1921                return rc;
1922            }
1923        } else {
1924            ALOGE("%s: ZSL channel is NULL", __func__);
1925            return UNKNOWN_ERROR;
1926        }
1927    } else {
1928        // normal capture case
1929        // need to stop preview channel
1930        stopChannel(QCAMERA_CH_TYPE_PREVIEW);
1931        delChannel(QCAMERA_CH_TYPE_PREVIEW);
1932
1933        // start snapshot
1934        if (mParameters.isJpegPictureFormat() ||
1935            mParameters.isNV16PictureFormat() ) {
1936            rc = addCaptureChannel();
1937            if (rc == NO_ERROR) {
1938                // start postprocessor
1939                m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_CAPTURE]);
1940
1941                // start catpure channel
1942                rc = startChannel(QCAMERA_CH_TYPE_CAPTURE);
1943                if (rc != NO_ERROR) {
1944                    ALOGE("%s: cannot start capture channel", __func__);
1945                    m_postprocessor.stop();
1946                    delChannel(QCAMERA_CH_TYPE_CAPTURE);
1947                    return rc;
1948                }
1949            } else {
1950                ALOGE("%s: cannot add capture channel", __func__);
1951                return rc;
1952            }
1953        } else {
1954            rc = addRawChannel();
1955            if (rc == NO_ERROR) {
1956                // start postprocessor
1957                m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
1958                rc = startChannel(QCAMERA_CH_TYPE_RAW);
1959                if (rc != NO_ERROR) {
1960                    ALOGE("%s: cannot start raw channel", __func__);
1961                    m_postprocessor.stop();
1962                    delChannel(QCAMERA_CH_TYPE_RAW);
1963                    return rc;
1964                }
1965            } else {
1966                ALOGE("%s: cannot add raw channel", __func__);
1967                return rc;
1968            }
1969        }
1970    }
1971    ALOGD("%s: X", __func__);
1972    return rc;
1973}
1974
1975/*===========================================================================
1976 * FUNCTION   : cancelPicture
1977 *
1978 * DESCRIPTION: cancel picture impl
1979 *
1980 * PARAMETERS : none
1981 *
1982 * RETURN     : int32_t type of status
1983 *              NO_ERROR  -- success
1984 *              none-zero failure code
1985 *==========================================================================*/
1986int QCamera2HardwareInterface::cancelPicture()
1987{
1988    //stop post processor
1989    m_postprocessor.stop();
1990
1991    if (mParameters.isZSLMode()) {
1992        QCameraPicChannel *pZSLChannel =
1993            (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
1994        if (NULL != pZSLChannel) {
1995            if (m_bStartZSLSnapshotCalled) {
1996                mCameraHandle->ops->stop_zsl_snapshot(
1997                        mCameraHandle->camera_handle);
1998                m_bStartZSLSnapshotCalled = false;
1999            }
2000            pZSLChannel->cancelPicture();
2001        }
2002    } else {
2003        // normal capture case
2004        if (mParameters.isJpegPictureFormat() ||
2005            mParameters.isNV16PictureFormat() ) {
2006            stopChannel(QCAMERA_CH_TYPE_CAPTURE);
2007            delChannel(QCAMERA_CH_TYPE_CAPTURE);
2008        } else {
2009            stopChannel(QCAMERA_CH_TYPE_RAW);
2010            delChannel(QCAMERA_CH_TYPE_RAW);
2011        }
2012    }
2013    return NO_ERROR;
2014}
2015
2016/*===========================================================================
2017 * FUNCTION   : takeLiveSnapshot
2018 *
2019 * DESCRIPTION: take live snapshot during recording
2020 *
2021 * PARAMETERS : none
2022 *
2023 * RETURN     : int32_t type of status
2024 *              NO_ERROR  -- success
2025 *              none-zero failure code
2026 *==========================================================================*/
2027int QCamera2HardwareInterface::takeLiveSnapshot()
2028{
2029    int rc = NO_ERROR;
2030
2031    // start post processor
2032    rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
2033
2034    // start snapshot channel
2035    if (rc == NO_ERROR) {
2036        rc = startChannel(QCAMERA_CH_TYPE_SNAPSHOT);
2037    }
2038    return rc;
2039}
2040
2041/*===========================================================================
2042 * FUNCTION   : cancelLiveSnapshot
2043 *
2044 * DESCRIPTION: cancel current live snapshot request
2045 *
2046 * PARAMETERS : none
2047 *
2048 * RETURN     : int32_t type of status
2049 *              NO_ERROR  -- success
2050 *              none-zero failure code
2051 *==========================================================================*/
2052int QCamera2HardwareInterface::cancelLiveSnapshot()
2053{
2054    int rc = NO_ERROR;
2055
2056    //stop post processor
2057    m_postprocessor.stop();
2058
2059    // stop snapshot channel
2060    rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
2061
2062    return rc;
2063}
2064
2065/*===========================================================================
2066 * FUNCTION   : getParameters
2067 *
2068 * DESCRIPTION: get parameters impl
2069 *
2070 * PARAMETERS : none
2071 *
2072 * RETURN     : a string containing parameter pairs
2073 *==========================================================================*/
2074char* QCamera2HardwareInterface::getParameters()
2075{
2076    char* strParams = NULL;
2077    String8 str;
2078    str = mParameters.flatten( );
2079    strParams = (char *)malloc(sizeof(char)*(str.length()+1));
2080    if(strParams != NULL){
2081        memset(strParams, 0, sizeof(char)*(str.length()+1));
2082        strncpy(strParams, str.string(), str.length());
2083        strParams[str.length()] = 0;
2084    }
2085    return strParams;
2086}
2087
2088/*===========================================================================
2089 * FUNCTION   : putParameters
2090 *
2091 * DESCRIPTION: put parameters string impl
2092 *
2093 * PARAMETERS :
2094 *   @parms   : parameters string to be released
2095 *
2096 * RETURN     : int32_t type of status
2097 *              NO_ERROR  -- success
2098 *              none-zero failure code
2099 *==========================================================================*/
2100int QCamera2HardwareInterface::putParameters(char *parms)
2101{
2102    free(parms);
2103    return NO_ERROR;
2104}
2105
2106/*===========================================================================
2107 * FUNCTION   : sendCommand
2108 *
2109 * DESCRIPTION: send command impl
2110 *
2111 * PARAMETERS :
2112 *   @command : command to be executed
2113 *   @arg1    : optional argument 1
2114 *   @arg2    : optional argument 2
2115 *
2116 * RETURN     : int32_t type of status
2117 *              NO_ERROR  -- success
2118 *              none-zero failure code
2119 *==========================================================================*/
2120int QCamera2HardwareInterface::sendCommand(int32_t command, int32_t /*arg1*/, int32_t /*arg2*/)
2121{
2122    int rc = NO_ERROR;
2123
2124    switch (command) {
2125    case CAMERA_CMD_START_FACE_DETECTION:
2126    case CAMERA_CMD_STOP_FACE_DETECTION:
2127        rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
2128        break;
2129    default:
2130        rc = NO_ERROR;
2131        break;
2132    }
2133    return rc;
2134}
2135
2136/*===========================================================================
2137 * FUNCTION   : registerFaceImage
2138 *
2139 * DESCRIPTION: register face image impl
2140 *
2141 * PARAMETERS :
2142 *   @img_ptr : ptr to image buffer
2143 *   @config  : ptr to config struct about input image info
2144 *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
2145 *
2146 * RETURN     : int32_t type of status
2147 *              NO_ERROR  -- success
2148 *              none-zero failure code
2149 *==========================================================================*/
2150int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
2151                                                 cam_pp_offline_src_config_t *config,
2152                                                 int32_t &faceID)
2153{
2154    int rc = NO_ERROR;
2155    faceID = -1;
2156
2157    if (img_ptr == NULL || config == NULL) {
2158        ALOGE("%s: img_ptr or config is NULL", __func__);
2159        return BAD_VALUE;
2160    }
2161
2162    // allocate ion memory for source image
2163    QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
2164    if (imgBuf == NULL) {
2165        ALOGE("%s: Unable to new heap memory obj for image buf", __func__);
2166        return NO_MEMORY;
2167    }
2168
2169    rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len);
2170    if (rc < 0) {
2171        ALOGE("%s: Unable to allocate heap memory for image buf", __func__);
2172        delete imgBuf;
2173        return NO_MEMORY;
2174    }
2175
2176    void *pBufPtr = imgBuf->getPtr(0);
2177    if (pBufPtr == NULL) {
2178        ALOGE("%s: image buf is NULL", __func__);
2179        imgBuf->deallocate();
2180        delete imgBuf;
2181        return NO_MEMORY;
2182    }
2183    memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
2184
2185    cam_pp_feature_config_t pp_feature;
2186    memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
2187    pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
2188    QCameraReprocessChannel *pChannel =
2189        addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
2190
2191    if (pChannel == NULL) {
2192        ALOGE("%s: fail to add offline reprocess channel", __func__);
2193        imgBuf->deallocate();
2194        delete imgBuf;
2195        return UNKNOWN_ERROR;
2196    }
2197
2198    rc = pChannel->start();
2199    if (rc != NO_ERROR) {
2200        ALOGE("%s: Cannot start reprocess channel", __func__);
2201        imgBuf->deallocate();
2202        delete imgBuf;
2203        delete pChannel;
2204        return rc;
2205    }
2206
2207    rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getSize(0), faceID);
2208
2209    // done with register face image, free imgbuf and delete reprocess channel
2210    imgBuf->deallocate();
2211    delete imgBuf;
2212    imgBuf = NULL;
2213    pChannel->stop();
2214    delete pChannel;
2215    pChannel = NULL;
2216
2217    return rc;
2218}
2219
2220/*===========================================================================
2221 * FUNCTION   : release
2222 *
2223 * DESCRIPTION: release camera resource impl
2224 *
2225 * PARAMETERS : none
2226 *
2227 * RETURN     : int32_t type of status
2228 *              NO_ERROR  -- success
2229 *              none-zero failure code
2230 *==========================================================================*/
2231int QCamera2HardwareInterface::release()
2232{
2233    // stop and delete all channels
2234    for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
2235        if (m_channels[i] != NULL) {
2236            stopChannel((qcamera_ch_type_enum_t)i);
2237            delChannel((qcamera_ch_type_enum_t)i);
2238        }
2239    }
2240
2241    return NO_ERROR;
2242}
2243
2244/*===========================================================================
2245 * FUNCTION   : dump
2246 *
2247 * DESCRIPTION: camera status dump impl
2248 *
2249 * PARAMETERS :
2250 *   @fd      : fd for the buffer to be dumped with camera status
2251 *
2252 * RETURN     : int32_t type of status
2253 *              NO_ERROR  -- success
2254 *              none-zero failure code
2255 *==========================================================================*/
2256int QCamera2HardwareInterface::dump(int /*fd*/)
2257{
2258    ALOGE("%s: not supported yet", __func__);
2259    return INVALID_OPERATION;
2260}
2261
2262/*===========================================================================
2263 * FUNCTION   : processAPI
2264 *
2265 * DESCRIPTION: process API calls from upper layer
2266 *
2267 * PARAMETERS :
2268 *   @api         : API to be processed
2269 *   @api_payload : ptr to API payload if any
2270 *
2271 * RETURN     : int32_t type of status
2272 *              NO_ERROR  -- success
2273 *              none-zero failure code
2274 *==========================================================================*/
2275int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
2276{
2277    return m_stateMachine.procAPI(api, api_payload);
2278}
2279
2280/*===========================================================================
2281 * FUNCTION   : processEvt
2282 *
2283 * DESCRIPTION: process Evt from backend via mm-camera-interface
2284 *
2285 * PARAMETERS :
2286 *   @evt         : event type to be processed
2287 *   @evt_payload : ptr to event payload if any
2288 *
2289 * RETURN     : int32_t type of status
2290 *              NO_ERROR  -- success
2291 *              none-zero failure code
2292 *==========================================================================*/
2293int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
2294{
2295    return m_stateMachine.procEvt(evt, evt_payload);
2296}
2297
2298/*===========================================================================
2299 * FUNCTION   : processSyncEvt
2300 *
2301 * DESCRIPTION: process synchronous Evt from backend
2302 *
2303 * PARAMETERS :
2304 *   @evt         : event type to be processed
2305 *   @evt_payload : ptr to event payload if any
2306 *
2307 * RETURN     : int32_t type of status
2308 *              NO_ERROR  -- success
2309 *              none-zero failure code
2310 *==========================================================================*/
2311int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
2312{
2313    int rc = NO_ERROR;
2314
2315    pthread_mutex_lock(&m_evtLock);
2316    rc =  processEvt(evt, evt_payload);
2317    if (rc == NO_ERROR) {
2318        memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
2319        while (m_evtResult.request_api != evt) {
2320            pthread_cond_wait(&m_evtCond, &m_evtLock);
2321        }
2322        rc =  m_evtResult.status;
2323    }
2324    pthread_mutex_unlock(&m_evtLock);
2325
2326    return rc;
2327}
2328
2329/*===========================================================================
2330 * FUNCTION   : evtHandle
2331 *
2332 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
2333 *
2334 * PARAMETERS :
2335 *   @camera_handle : event type to be processed
2336 *   @evt           : ptr to event
2337 *   @user_data     : user data ptr
2338 *
2339 * RETURN     : none
2340 *==========================================================================*/
2341void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
2342                                          mm_camera_event_t *evt,
2343                                          void *user_data)
2344{
2345    QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
2346    if (obj && evt) {
2347        mm_camera_event_t *payload =
2348            (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
2349        if (NULL != payload) {
2350            *payload = *evt;
2351            obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
2352        }
2353    } else {
2354        ALOGE("%s: NULL user_data", __func__);
2355    }
2356}
2357
2358/*===========================================================================
2359 * FUNCTION   : jpegEvtHandle
2360 *
2361 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
2362 *
2363 * PARAMETERS :
2364 *   @status    : status of jpeg job
2365 *   @client_hdl: jpeg client handle
2366 *   @jobId     : jpeg job Id
2367 *   @p_ouput   : ptr to jpeg output result struct
2368 *   @userdata  : user data ptr
2369 *
2370 * RETURN     : none
2371 *==========================================================================*/
2372void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
2373                                              uint32_t /*client_hdl*/,
2374                                              uint32_t jobId,
2375                                              mm_jpeg_output_t *p_output,
2376                                              void *userdata)
2377{
2378    QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
2379    if (obj) {
2380        qcamera_jpeg_evt_payload_t *payload =
2381            (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
2382        if (NULL != payload) {
2383            memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
2384            payload->status = status;
2385            payload->jobId = jobId;
2386            if (p_output != NULL) {
2387                payload->out_data = *p_output;
2388            }
2389            obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
2390        }
2391    } else {
2392        ALOGE("%s: NULL user_data", __func__);
2393    }
2394}
2395
2396/*===========================================================================
2397 * FUNCTION   : thermalEvtHandle
2398 *
2399 * DESCRIPTION: routine to handle thermal event notification
2400 *
2401 * PARAMETERS :
2402 *   @level      : thermal level
2403 *   @userdata   : userdata passed in during registration
2404 *   @data       : opaque data from thermal client
2405 *
2406 * RETURN     : int32_t type of status
2407 *              NO_ERROR  -- success
2408 *              none-zero failure code
2409 *==========================================================================*/
2410int QCamera2HardwareInterface::thermalEvtHandle(
2411        qcamera_thermal_level_enum_t level, void *userdata, void *data)
2412{
2413    // Make sure thermal events are logged
2414    ALOGI("%s: level = %d, userdata = %p, data = %p",
2415        __func__, level, userdata, data);
2416    //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
2417    // becomes an aync call. This also means we can only pass payload
2418    // by value, not by address.
2419    return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
2420}
2421
2422/*===========================================================================
2423 * FUNCTION   : sendEvtNotify
2424 *
2425 * DESCRIPTION: send event notify to notify thread
2426 *
2427 * PARAMETERS :
2428 *   @msg_type: msg type to be sent
2429 *   @ext1    : optional extension1
2430 *   @ext2    : optional extension2
2431 *
2432 * RETURN     : int32_t type of status
2433 *              NO_ERROR  -- success
2434 *              none-zero failure code
2435 *==========================================================================*/
2436int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
2437                                                 int32_t ext1,
2438                                                 int32_t ext2)
2439{
2440    qcamera_callback_argm_t cbArg;
2441    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
2442    cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
2443    cbArg.msg_type = msg_type;
2444    cbArg.ext1 = ext1;
2445    cbArg.ext2 = ext2;
2446    return m_cbNotifier.notifyCallback(cbArg);
2447}
2448
2449/*===========================================================================
2450 * FUNCTION   : processAutoFocusEvent
2451 *
2452 * DESCRIPTION: process auto focus event
2453 *
2454 * PARAMETERS :
2455 *   @focus_data: struct containing auto focus result info
2456 *
2457 * RETURN     : int32_t type of status
2458 *              NO_ERROR  -- success
2459 *              none-zero failure code
2460 *==========================================================================*/
2461int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
2462{
2463    int32_t ret = NO_ERROR;
2464
2465    m_currentFocusState = focus_data.focus_state;
2466
2467    cam_focus_mode_type focusMode = mParameters.getFocusMode();
2468    switch (focusMode) {
2469    case CAM_FOCUS_MODE_AUTO:
2470    case CAM_FOCUS_MODE_MACRO:
2471        if (mParameters.isAFRunning()) {
2472            if (focus_data.focus_state == CAM_AF_SCANNING) {
2473                // in the middle of focusing, just ignore it
2474                break;
2475            }
2476
2477            // update focus distance
2478            mParameters.updateFocusDistances(&focus_data.focus_dist);
2479            ret = sendEvtNotify(CAMERA_MSG_FOCUS,
2480                                (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
2481                                0);
2482            mParameters.setAFRunning(false);
2483        } else {
2484            ret = UNKNOWN_ERROR;
2485            ALOGE("%s: autoFocusEvent when no auto_focus running", __func__);
2486        }
2487        break;
2488    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
2489    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
2490        if (focus_data.focus_state == CAM_AF_FOCUSED ||
2491            focus_data.focus_state == CAM_AF_NOT_FOCUSED) {
2492            // update focus distance
2493            mParameters.updateFocusDistances(&focus_data.focus_dist);
2494            if (mParameters.isLockCAFNeeded()) {
2495                mParameters.setLockCAFNeeded(false);
2496                ret = mParameters.setLockCAF(true);
2497            }
2498
2499            ret = sendEvtNotify(CAMERA_MSG_FOCUS,
2500                  (focus_data.focus_state == CAM_AF_FOCUSED)? true : false,
2501                  0);
2502        }
2503        ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
2504                (focus_data.focus_state == CAM_AF_SCANNING)? true : false,
2505                0);
2506        break;
2507    case CAM_FOCUS_MODE_INFINITY:
2508    case CAM_FOCUS_MODE_FIXED:
2509    case CAM_FOCUS_MODE_EDOF:
2510    default:
2511        ALOGD("%s: no ops for autofocus event in focusmode %d", __func__, focusMode);
2512        break;
2513    }
2514
2515    return ret;
2516}
2517
2518/*===========================================================================
2519 * FUNCTION   : processZoomEvent
2520 *
2521 * DESCRIPTION: process zoom event
2522 *
2523 * PARAMETERS :
2524 *   @crop_info : crop info as a result of zoom operation
2525 *
2526 * RETURN     : int32_t type of status
2527 *              NO_ERROR  -- success
2528 *              none-zero failure code
2529 *==========================================================================*/
2530int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
2531{
2532    int32_t ret = NO_ERROR;
2533
2534    for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2535        if (m_channels[i] != NULL) {
2536            ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
2537        }
2538    }
2539    return ret;
2540}
2541
2542/*===========================================================================
2543 * FUNCTION   : processPrepSnapshotDone
2544 *
2545 * DESCRIPTION: process prep snapshot done event
2546 *
2547 * PARAMETERS :
2548 *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
2549 *                           i.e. whether need future frames for capture.
2550 *
2551 * RETURN     : int32_t type of status
2552 *              NO_ERROR  -- success
2553 *              none-zero failure code
2554 *==========================================================================*/
2555int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
2556                        cam_prep_snapshot_state_t prep_snapshot_state)
2557{
2558    int32_t ret = NO_ERROR;
2559
2560    if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
2561        prep_snapshot_state == NEED_FUTURE_FRAME) {
2562
2563        ret = mCameraHandle->ops->start_zsl_snapshot(
2564                            mCameraHandle->camera_handle);
2565        if (ret < 0) {
2566            ALOGE("%s: start_led_zsl_capture failed %d",
2567                            __func__, ret);
2568            return ret;
2569        }
2570        m_bStartZSLSnapshotCalled = true;
2571    }
2572    return ret;
2573}
2574
2575/*===========================================================================
2576 * FUNCTION   : processJpegNotify
2577 *
2578 * DESCRIPTION: process jpeg event
2579 *
2580 * PARAMETERS :
2581 *   @jpeg_evt: ptr to jpeg event payload
2582 *
2583 * RETURN     : int32_t type of status
2584 *              NO_ERROR  -- success
2585 *              none-zero failure code
2586 *==========================================================================*/
2587int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
2588{
2589    return m_postprocessor.processJpegEvt(jpeg_evt);
2590}
2591
2592/*===========================================================================
2593 * FUNCTION   : lockAPI
2594 *
2595 * DESCRIPTION: lock to process API
2596 *
2597 * PARAMETERS : none
2598 *
2599 * RETURN     : none
2600 *==========================================================================*/
2601void QCamera2HardwareInterface::lockAPI()
2602{
2603    pthread_mutex_lock(&m_lock);
2604}
2605
2606/*===========================================================================
2607 * FUNCTION   : waitAPIResult
2608 *
2609 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
2610 *              return only cerntain API event type arrives
2611 *
2612 * PARAMETERS :
2613 *   @api_evt : API event type
2614 *
2615 * RETURN     : none
2616 *==========================================================================*/
2617void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt)
2618{
2619    ALOGV("%s: wait for API result of evt (%d)", __func__, api_evt);
2620    memset(&m_apiResult, 0, sizeof(qcamera_api_result_t));
2621    while (m_apiResult.request_api != api_evt) {
2622        pthread_cond_wait(&m_cond, &m_lock);
2623    }
2624    ALOGV("%s: return (%d) from API result wait for evt (%d)",
2625          __func__, m_apiResult.status, api_evt);
2626}
2627
2628/*===========================================================================
2629 * FUNCTION   : unlockAPI
2630 *
2631 * DESCRIPTION: API processing is done, unlock
2632 *
2633 * PARAMETERS : none
2634 *
2635 * RETURN     : none
2636 *==========================================================================*/
2637void QCamera2HardwareInterface::unlockAPI()
2638{
2639    pthread_mutex_unlock(&m_lock);
2640}
2641
2642/*===========================================================================
2643 * FUNCTION   : signalAPIResult
2644 *
2645 * DESCRIPTION: signal condition viarable that cerntain API event type arrives
2646 *
2647 * PARAMETERS :
2648 *   @result  : API result
2649 *
2650 * RETURN     : none
2651 *==========================================================================*/
2652void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
2653{
2654    pthread_mutex_lock(&m_lock);
2655    m_apiResult = *result;
2656    pthread_cond_signal(&m_cond);
2657    pthread_mutex_unlock(&m_lock);
2658}
2659
2660/*===========================================================================
2661 * FUNCTION   : signalEvtResult
2662 *
2663 * DESCRIPTION: signal condition variable that certain event was processed
2664 *
2665 * PARAMETERS :
2666 *   @result  : Event result
2667 *
2668 * RETURN     : none
2669 *==========================================================================*/
2670void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
2671{
2672    pthread_mutex_lock(&m_evtLock);
2673    m_evtResult = *result;
2674    pthread_cond_signal(&m_evtCond);
2675    pthread_mutex_unlock(&m_evtLock);
2676}
2677
2678/*===========================================================================
2679 * FUNCTION   : addStreamToChannel
2680 *
2681 * DESCRIPTION: add a stream into a channel
2682 *
2683 * PARAMETERS :
2684 *   @pChannel   : ptr to channel obj
2685 *   @streamType : type of stream to be added
2686 *   @streamCB   : callback of stream
2687 *   @userData   : user data ptr to callback
2688 *
2689 * RETURN     : int32_t type of status
2690 *              NO_ERROR  -- success
2691 *              none-zero failure code
2692 *==========================================================================*/
2693int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
2694                                                      cam_stream_type_t streamType,
2695                                                      stream_cb_routine streamCB,
2696                                                      void *userData)
2697{
2698    int32_t rc = NO_ERROR;
2699    QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
2700    if (pStreamInfo == NULL) {
2701        ALOGE("%s: no mem for stream info buf", __func__);
2702        return NO_MEMORY;
2703    }
2704    uint8_t minStreamBufNum = getBufNumRequired(streamType);
2705    rc = pChannel->addStream(*this,
2706                             pStreamInfo,
2707                             minStreamBufNum,
2708                             &gCamCapability[mCameraId]->padding_info,
2709                             streamCB, userData);
2710    if (rc != NO_ERROR) {
2711        ALOGE("%s: add stream type (%d) failed, ret = %d",
2712              __func__, streamType, rc);
2713        pStreamInfo->deallocate();
2714        delete pStreamInfo;
2715        return rc;
2716    }
2717
2718    return rc;
2719}
2720
2721/*===========================================================================
2722 * FUNCTION   : addPreviewChannel
2723 *
2724 * DESCRIPTION: add a preview channel that contains a preview stream
2725 *
2726 * PARAMETERS : none
2727 *
2728 * RETURN     : int32_t type of status
2729 *              NO_ERROR  -- success
2730 *              none-zero failure code
2731 *==========================================================================*/
2732int32_t QCamera2HardwareInterface::addPreviewChannel()
2733{
2734    int32_t rc = NO_ERROR;
2735    QCameraChannel *pChannel = NULL;
2736
2737    if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
2738        // if we had preview channel before, delete it first
2739        delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
2740        m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
2741    }
2742
2743    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2744                                  mCameraHandle->ops);
2745    if (NULL == pChannel) {
2746        ALOGE("%s: no mem for preview channel", __func__);
2747        return NO_MEMORY;
2748    }
2749
2750    // preview only channel, don't need bundle attr and cb
2751    rc = pChannel->init(NULL, NULL, NULL);
2752    if (rc != NO_ERROR) {
2753        ALOGE("%s: init preview channel failed, ret = %d", __func__, rc);
2754        delete pChannel;
2755        return rc;
2756    }
2757
2758    // meta data stream always coexists with preview if applicable
2759    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2760                            metadata_stream_cb_routine, this);
2761    if (rc != NO_ERROR) {
2762        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2763        delete pChannel;
2764        return rc;
2765    }
2766
2767    if (isNoDisplayMode()) {
2768        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2769                                nodisplay_preview_stream_cb_routine, this);
2770    } else {
2771        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2772                                preview_stream_cb_routine, this);
2773    }
2774    if (rc != NO_ERROR) {
2775        ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
2776        delete pChannel;
2777        return rc;
2778    }
2779
2780    m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
2781    return rc;
2782}
2783
2784/*===========================================================================
2785 * FUNCTION   : addVideoChannel
2786 *
2787 * DESCRIPTION: add a video channel that contains a video stream
2788 *
2789 * PARAMETERS : none
2790 *
2791 * RETURN     : int32_t type of status
2792 *              NO_ERROR  -- success
2793 *              none-zero failure code
2794 *==========================================================================*/
2795int32_t QCamera2HardwareInterface::addVideoChannel()
2796{
2797    int32_t rc = NO_ERROR;
2798    QCameraVideoChannel *pChannel = NULL;
2799
2800    if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
2801        // if we had video channel before, delete it first
2802        delete m_channels[QCAMERA_CH_TYPE_VIDEO];
2803        m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
2804    }
2805
2806    pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
2807                                       mCameraHandle->ops);
2808    if (NULL == pChannel) {
2809        ALOGE("%s: no mem for video channel", __func__);
2810        return NO_MEMORY;
2811    }
2812
2813    // preview only channel, don't need bundle attr and cb
2814    rc = pChannel->init(NULL, NULL, NULL);
2815    if (rc != 0) {
2816        ALOGE("%s: init video channel failed, ret = %d", __func__, rc);
2817        delete pChannel;
2818        return rc;
2819    }
2820
2821    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
2822                            video_stream_cb_routine, this);
2823    if (rc != NO_ERROR) {
2824        ALOGE("%s: add video stream failed, ret = %d", __func__, rc);
2825        delete pChannel;
2826        return rc;
2827    }
2828
2829    m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
2830    return rc;
2831}
2832
2833/*===========================================================================
2834 * FUNCTION   : addSnapshotChannel
2835 *
2836 * DESCRIPTION: add a snapshot channel that contains a snapshot stream
2837 *
2838 * PARAMETERS : none
2839 *
2840 * RETURN     : int32_t type of status
2841 *              NO_ERROR  -- success
2842 *              none-zero failure code
2843 * NOTE       : Add this channel for live snapshot usecase. Regular capture will
2844 *              use addCaptureChannel.
2845 *==========================================================================*/
2846int32_t QCamera2HardwareInterface::addSnapshotChannel()
2847{
2848    int32_t rc = NO_ERROR;
2849    QCameraChannel *pChannel = NULL;
2850
2851    if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
2852        // if we had ZSL channel before, delete it first
2853        delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
2854        m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
2855    }
2856
2857    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2858                                  mCameraHandle->ops);
2859    if (NULL == pChannel) {
2860        ALOGE("%s: no mem for snapshot channel", __func__);
2861        return NO_MEMORY;
2862    }
2863
2864    rc = pChannel->init(NULL, NULL, NULL);
2865    if (rc != NO_ERROR) {
2866        ALOGE("%s: init snapshot channel failed, ret = %d", __func__, rc);
2867        delete pChannel;
2868        return rc;
2869    }
2870
2871    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT,
2872                            snapshot_stream_cb_routine, this);
2873    if (rc != NO_ERROR) {
2874        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
2875        delete pChannel;
2876        return rc;
2877    }
2878
2879    m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
2880    return rc;
2881}
2882
2883/*===========================================================================
2884 * FUNCTION   : addRawChannel
2885 *
2886 * DESCRIPTION: add a raw channel that contains a raw image stream
2887 *
2888 * PARAMETERS : none
2889 *
2890 * RETURN     : int32_t type of status
2891 *              NO_ERROR  -- success
2892 *              none-zero failure code
2893 *==========================================================================*/
2894int32_t QCamera2HardwareInterface::addRawChannel()
2895{
2896    int32_t rc = NO_ERROR;
2897    QCameraChannel *pChannel = NULL;
2898
2899    if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
2900        // if we had raw channel before, delete it first
2901        delete m_channels[QCAMERA_CH_TYPE_RAW];
2902        m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
2903    }
2904
2905    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
2906                                  mCameraHandle->ops);
2907    if (NULL == pChannel) {
2908        ALOGE("%s: no mem for raw channel", __func__);
2909        return NO_MEMORY;
2910    }
2911
2912    rc = pChannel->init(NULL, NULL, NULL);
2913    if (rc != NO_ERROR) {
2914        ALOGE("%s: init raw channel failed, ret = %d", __func__, rc);
2915        delete pChannel;
2916        return rc;
2917    }
2918
2919    // meta data stream always coexists with snapshot in regular RAW capture case
2920    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2921                            metadata_stream_cb_routine, this);
2922    if (rc != NO_ERROR) {
2923        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2924        delete pChannel;
2925        return rc;
2926    }
2927
2928    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
2929                            raw_stream_cb_routine, this);
2930    if (rc != NO_ERROR) {
2931        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
2932        delete pChannel;
2933        return rc;
2934    }
2935
2936    m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
2937    return rc;
2938}
2939
2940/*===========================================================================
2941 * FUNCTION   : addZSLChannel
2942 *
2943 * DESCRIPTION: add a ZSL channel that contains a preview stream and
2944 *              a snapshot stream
2945 *
2946 * PARAMETERS : none
2947 *
2948 * RETURN     : int32_t type of status
2949 *              NO_ERROR  -- success
2950 *              none-zero failure code
2951 *==========================================================================*/
2952int32_t QCamera2HardwareInterface::addZSLChannel()
2953{
2954    int32_t rc = NO_ERROR;
2955    QCameraPicChannel *pChannel = NULL;
2956
2957    if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
2958        // if we had ZSL channel before, delete it first
2959        delete m_channels[QCAMERA_CH_TYPE_ZSL];
2960        m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
2961    }
2962
2963    pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
2964                                     mCameraHandle->ops);
2965    if (NULL == pChannel) {
2966        ALOGE("%s: no mem for ZSL channel", __func__);
2967        return NO_MEMORY;
2968    }
2969
2970    // ZSL channel, init with bundle attr and cb
2971    mm_camera_channel_attr_t attr;
2972    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
2973    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
2974    attr.look_back = mParameters.getZSLBackLookCount();
2975    attr.post_frame_skip = mParameters.getZSLBurstInterval();
2976    attr.water_mark = mParameters.getZSLQueueDepth();
2977    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
2978    rc = pChannel->init(&attr,
2979                        zsl_channel_cb,
2980                        this);
2981    if (rc != 0) {
2982        ALOGE("%s: init ZSL channel failed, ret = %d", __func__, rc);
2983        delete pChannel;
2984        return rc;
2985    }
2986
2987    // meta data stream always coexists with preview if applicable
2988    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
2989                            metadata_stream_cb_routine, this);
2990    if (rc != NO_ERROR) {
2991        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
2992        delete pChannel;
2993        return rc;
2994    }
2995
2996    if (isNoDisplayMode()) {
2997        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
2998                                nodisplay_preview_stream_cb_routine, this);
2999    } else {
3000        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
3001                                preview_stream_cb_routine, this);
3002    }
3003    if (rc != NO_ERROR) {
3004        ALOGE("%s: add preview stream failed, ret = %d", __func__, rc);
3005        delete pChannel;
3006        return rc;
3007    }
3008
3009    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
3010                            NULL, this);
3011    if (rc != NO_ERROR) {
3012        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
3013        delete pChannel;
3014        return rc;
3015    }
3016
3017    m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
3018    return rc;
3019}
3020
3021/*===========================================================================
3022 * FUNCTION   : addCaptureChannel
3023 *
3024 * DESCRIPTION: add a capture channel that contains a snapshot stream
3025 *              and a postview stream
3026 *
3027 * PARAMETERS : none
3028 *
3029 * RETURN     : int32_t type of status
3030 *              NO_ERROR  -- success
3031 *              none-zero failure code
3032 * NOTE       : Add this channel for regular capture usecase.
3033 *              For Live snapshot usecase, use addSnapshotChannel.
3034 *==========================================================================*/
3035int32_t QCamera2HardwareInterface::addCaptureChannel()
3036{
3037    int32_t rc = NO_ERROR;
3038    QCameraChannel *pChannel = NULL;
3039
3040    if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
3041        delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
3042        m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
3043    }
3044
3045    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
3046                                  mCameraHandle->ops);
3047    if (NULL == pChannel) {
3048        ALOGE("%s: no mem for capture channel", __func__);
3049        return NO_MEMORY;
3050    }
3051
3052    // Capture channel, only need snapshot and postview streams start together
3053    mm_camera_channel_attr_t attr;
3054    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
3055    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
3056    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
3057
3058    rc = pChannel->init(&attr,
3059                        capture_channel_cb_routine,
3060                        this);
3061    if (rc != NO_ERROR) {
3062        ALOGE("%s: init capture channel failed, ret = %d", __func__, rc);
3063        delete pChannel;
3064        return rc;
3065    }
3066
3067
3068    // meta data stream always coexists with snapshot in regular capture case
3069    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
3070                            metadata_stream_cb_routine, this);
3071    if (rc != NO_ERROR) {
3072        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
3073        delete pChannel;
3074        return rc;
3075    }
3076
3077    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
3078                            postview_stream_cb_routine, this);
3079
3080    if (rc != NO_ERROR) {
3081        ALOGE("%s: add postview stream failed, ret = %d", __func__, rc);
3082        delete pChannel;
3083        return rc;
3084    }
3085
3086    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT,
3087                            NULL, this);
3088    if (rc != NO_ERROR) {
3089        ALOGE("%s: add snapshot stream failed, ret = %d", __func__, rc);
3090        delete pChannel;
3091        return rc;
3092    }
3093
3094    m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
3095    return rc;
3096}
3097
3098/*===========================================================================
3099 * FUNCTION   : addMetaDataChannel
3100 *
3101 * DESCRIPTION: add a meta data channel that contains a metadata stream
3102 *
3103 * PARAMETERS : none
3104 *
3105 * RETURN     : int32_t type of status
3106 *              NO_ERROR  -- success
3107 *              none-zero failure code
3108 *==========================================================================*/
3109int32_t QCamera2HardwareInterface::addMetaDataChannel()
3110{
3111    int32_t rc = NO_ERROR;
3112    QCameraChannel *pChannel = NULL;
3113
3114    if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
3115        delete m_channels[QCAMERA_CH_TYPE_METADATA];
3116        m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
3117    }
3118
3119    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
3120                                  mCameraHandle->ops);
3121    if (NULL == pChannel) {
3122        ALOGE("%s: no mem for metadata channel", __func__);
3123        return NO_MEMORY;
3124    }
3125
3126    rc = pChannel->init(NULL,
3127                        NULL,
3128                        NULL);
3129    if (rc != NO_ERROR) {
3130        ALOGE("%s: init metadata channel failed, ret = %d", __func__, rc);
3131        delete pChannel;
3132        return rc;
3133    }
3134
3135    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
3136                            metadata_stream_cb_routine, this);
3137    if (rc != NO_ERROR) {
3138        ALOGE("%s: add metadata stream failed, ret = %d", __func__, rc);
3139        delete pChannel;
3140        return rc;
3141    }
3142
3143    m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
3144    return rc;
3145}
3146
3147/*===========================================================================
3148 * FUNCTION   : addOnlineReprocChannel
3149 *
3150 * DESCRIPTION: add a online reprocess channel that will do reprocess on frames
3151 *              coming from input channel
3152 *
3153 * PARAMETERS :
3154 *   @pInputChannel : ptr to input channel whose frames will be post-processed
3155 *
3156 * RETURN     : Ptr to the newly created channel obj. NULL if failed.
3157 *==========================================================================*/
3158QCameraReprocessChannel *QCamera2HardwareInterface::addOnlineReprocChannel(
3159                                                      QCameraChannel *pInputChannel)
3160{
3161    int32_t rc = NO_ERROR;
3162    QCameraReprocessChannel *pChannel = NULL;
3163
3164    if (pInputChannel == NULL) {
3165        ALOGE("%s: input channel obj is NULL", __func__);
3166        return NULL;
3167    }
3168
3169    pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
3170                                           mCameraHandle->ops);
3171    if (NULL == pChannel) {
3172        ALOGE("%s: no mem for reprocess channel", __func__);
3173        return NULL;
3174    }
3175
3176    // Capture channel, only need snapshot and postview streams start together
3177    mm_camera_channel_attr_t attr;
3178    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
3179    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
3180    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
3181    rc = pChannel->init(&attr,
3182                        postproc_channel_cb_routine,
3183                        this);
3184    if (rc != NO_ERROR) {
3185        ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
3186        delete pChannel;
3187        return NULL;
3188    }
3189
3190    // pp feature config
3191    cam_pp_feature_config_t pp_config;
3192    memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
3193    if (gCamCapability[mCameraId]->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3194        pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
3195        pp_config.sharpness = mParameters.getInt(QCameraParameters::KEY_QC_SHARPNESS);
3196    }
3197
3198    if (mParameters.isWNREnabled()) {
3199        pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
3200        pp_config.denoise2d.denoise_enable = 1;
3201        pp_config.denoise2d.process_plates = mParameters.getWaveletDenoiseProcessPlate();
3202    }
3203
3204    if (isCACEnabled()) {
3205        pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
3206    }
3207
3208    if (needRotationReprocess()) {
3209        pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
3210        int rotation = mParameters.getJpegRotation();
3211        if (rotation == 0) {
3212            pp_config.rotation = ROTATE_0;
3213        } else if (rotation == 90) {
3214            pp_config.rotation = ROTATE_90;
3215        } else if (rotation == 180) {
3216            pp_config.rotation = ROTATE_180;
3217        } else if (rotation == 270) {
3218            pp_config.rotation = ROTATE_270;
3219        }
3220    }
3221
3222    uint8_t minStreamBufNum = mParameters.getNumOfSnapshots();
3223    rc = pChannel->addReprocStreamsFromSource(*this,
3224                                              pp_config,
3225                                              pInputChannel,
3226                                              minStreamBufNum,
3227                                              &gCamCapability[mCameraId]->padding_info);
3228    if (rc != NO_ERROR) {
3229        delete pChannel;
3230        return NULL;
3231    }
3232
3233    return pChannel;
3234}
3235
3236/*===========================================================================
3237 * FUNCTION   : addOfflineReprocChannel
3238 *
3239 * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
3240 *              that will do reprocess on frames coming from external images
3241 *
3242 * PARAMETERS :
3243 *   @img_config  : offline reporcess image info
3244 *   @pp_feature  : pp feature config
3245 *
3246 * RETURN     : int32_t type of status
3247 *              NO_ERROR  -- success
3248 *              none-zero failure code
3249 *==========================================================================*/
3250QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
3251                                            cam_pp_offline_src_config_t &img_config,
3252                                            cam_pp_feature_config_t &pp_feature,
3253                                            stream_cb_routine stream_cb,
3254                                            void *userdata)
3255{
3256    int32_t rc = NO_ERROR;
3257    QCameraReprocessChannel *pChannel = NULL;
3258
3259    pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
3260                                           mCameraHandle->ops);
3261    if (NULL == pChannel) {
3262        ALOGE("%s: no mem for reprocess channel", __func__);
3263        return NULL;
3264    }
3265
3266    rc = pChannel->init(NULL, NULL, NULL);
3267    if (rc != NO_ERROR) {
3268        ALOGE("%s: init reprocess channel failed, ret = %d", __func__, rc);
3269        delete pChannel;
3270        return NULL;
3271    }
3272
3273    QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
3274    if (pStreamInfo == NULL) {
3275        ALOGE("%s: no mem for stream info buf", __func__);
3276        delete pChannel;
3277        return NULL;
3278    }
3279
3280    cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
3281    memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
3282    streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
3283    streamInfoBuf->fmt = img_config.input_fmt;
3284    streamInfoBuf->dim = img_config.input_dim;
3285    streamInfoBuf->buf_planes = img_config.input_buf_planes;
3286    streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
3287    streamInfoBuf->num_of_burst = img_config.num_of_bufs;
3288
3289    streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
3290    streamInfoBuf->reprocess_config.offline = img_config;
3291    streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
3292
3293    rc = pChannel->addStream(*this,
3294                             pStreamInfo, img_config.num_of_bufs,
3295                             &gCamCapability[mCameraId]->padding_info,
3296                             stream_cb, userdata);
3297
3298    if (rc != NO_ERROR) {
3299        ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
3300        pStreamInfo->deallocate();
3301        delete pStreamInfo;
3302        delete pChannel;
3303        return NULL;
3304    }
3305
3306    return pChannel;
3307}
3308
3309/*===========================================================================
3310 * FUNCTION   : addChannel
3311 *
3312 * DESCRIPTION: add a channel by its type
3313 *
3314 * PARAMETERS :
3315 *   @ch_type : channel type
3316 *
3317 * RETURN     : int32_t type of status
3318 *              NO_ERROR  -- success
3319 *              none-zero failure code
3320 *==========================================================================*/
3321int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
3322{
3323    int32_t rc = UNKNOWN_ERROR;
3324    switch (ch_type) {
3325    case QCAMERA_CH_TYPE_ZSL:
3326        rc = addZSLChannel();
3327        break;
3328    case QCAMERA_CH_TYPE_CAPTURE:
3329        rc = addCaptureChannel();
3330        break;
3331    case QCAMERA_CH_TYPE_PREVIEW:
3332        rc = addPreviewChannel();
3333        break;
3334    case QCAMERA_CH_TYPE_VIDEO:
3335        rc = addVideoChannel();
3336        break;
3337    case QCAMERA_CH_TYPE_SNAPSHOT:
3338        rc = addSnapshotChannel();
3339        break;
3340    case QCAMERA_CH_TYPE_RAW:
3341        rc = addRawChannel();
3342        break;
3343    case QCAMERA_CH_TYPE_METADATA:
3344        rc = addMetaDataChannel();
3345        break;
3346    default:
3347        break;
3348    }
3349    return rc;
3350}
3351
3352/*===========================================================================
3353 * FUNCTION   : delChannel
3354 *
3355 * DESCRIPTION: delete a channel by its type
3356 *
3357 * PARAMETERS :
3358 *   @ch_type : channel type
3359 *
3360 * RETURN     : int32_t type of status
3361 *              NO_ERROR  -- success
3362 *              none-zero failure code
3363 *==========================================================================*/
3364int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type)
3365{
3366    if (m_channels[ch_type] != NULL) {
3367        delete m_channels[ch_type];
3368        m_channels[ch_type] = NULL;
3369    }
3370
3371    return NO_ERROR;
3372}
3373
3374/*===========================================================================
3375 * FUNCTION   : startChannel
3376 *
3377 * DESCRIPTION: start a channel by its type
3378 *
3379 * PARAMETERS :
3380 *   @ch_type : channel type
3381 *
3382 * RETURN     : int32_t type of status
3383 *              NO_ERROR  -- success
3384 *              none-zero failure code
3385 *==========================================================================*/
3386int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
3387{
3388    int32_t rc = UNKNOWN_ERROR;
3389    if (m_channels[ch_type] != NULL) {
3390        rc = m_channels[ch_type]->start();
3391    }
3392
3393    return rc;
3394}
3395
3396/*===========================================================================
3397 * FUNCTION   : stopChannel
3398 *
3399 * DESCRIPTION: stop a channel by its type
3400 *
3401 * PARAMETERS :
3402 *   @ch_type : channel type
3403 *
3404 * RETURN     : int32_t type of status
3405 *              NO_ERROR  -- success
3406 *              none-zero failure code
3407 *==========================================================================*/
3408int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
3409{
3410    int32_t rc = UNKNOWN_ERROR;
3411    if (m_channels[ch_type] != NULL) {
3412        rc = m_channels[ch_type]->stop();
3413    }
3414
3415    return rc;
3416}
3417
3418/*===========================================================================
3419 * FUNCTION   : preparePreview
3420 *
3421 * DESCRIPTION: add channels needed for preview
3422 *
3423 * PARAMETERS : none
3424 *
3425 * RETURN     : int32_t type of status
3426 *              NO_ERROR  -- success
3427 *              none-zero failure code
3428 *==========================================================================*/
3429int32_t QCamera2HardwareInterface::preparePreview()
3430{
3431    int32_t rc = NO_ERROR;
3432
3433    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
3434        rc = addChannel(QCAMERA_CH_TYPE_ZSL);
3435        if (rc != NO_ERROR) {
3436            return rc;
3437        }
3438    } else {
3439        bool recordingHint = mParameters.getRecordingHintValue();
3440        if(recordingHint) {
3441            rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3442            if (rc != NO_ERROR) {
3443                return rc;
3444            }
3445
3446            rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
3447            if (rc != NO_ERROR) {
3448                delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3449                return rc;
3450            }
3451        }
3452
3453        rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
3454        if (rc != NO_ERROR) {
3455            if (recordingHint) {
3456                delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3457                delChannel(QCAMERA_CH_TYPE_VIDEO);
3458            }
3459            return rc;
3460        }
3461
3462    }
3463
3464    return rc;
3465}
3466
3467/*===========================================================================
3468 * FUNCTION   : unpreparePreview
3469 *
3470 * DESCRIPTION: delete channels for preview
3471 *
3472 * PARAMETERS : none
3473 *
3474 * RETURN     : none
3475 *==========================================================================*/
3476void QCamera2HardwareInterface::unpreparePreview()
3477{
3478    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() !=true) {
3479        delChannel(QCAMERA_CH_TYPE_ZSL);
3480    } else {
3481        delChannel(QCAMERA_CH_TYPE_PREVIEW);
3482        if(mParameters.getRecordingHintValue() == true) {
3483            delChannel(QCAMERA_CH_TYPE_VIDEO);
3484            delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
3485        }
3486    }
3487}
3488
3489/*===========================================================================
3490 * FUNCTION   : playShutter
3491 *
3492 * DESCRIPTION: send request to play shutter sound
3493 *
3494 * PARAMETERS : none
3495 *
3496 * RETURN     : none
3497 *==========================================================================*/
3498void QCamera2HardwareInterface::playShutter(){
3499     if (mNotifyCb == NULL ||
3500         msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
3501         ALOGV("%s: shutter msg not enabled or NULL cb", __func__);
3502         return;
3503     }
3504
3505     qcamera_callback_argm_t cbArg;
3506     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3507     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
3508     cbArg.msg_type = CAMERA_MSG_SHUTTER;
3509     cbArg.ext1 = 0;
3510
3511     if(!m_bShutterSoundPlayed){
3512         cbArg.ext2 = true;
3513         m_cbNotifier.notifyCallback(cbArg);
3514     }
3515     cbArg.ext2 = false;
3516     m_cbNotifier.notifyCallback(cbArg);
3517     m_bShutterSoundPlayed = false;
3518}
3519
3520/*===========================================================================
3521 * FUNCTION   : getChannelByHandle
3522 *
3523 * DESCRIPTION: return a channel by its handle
3524 *
3525 * PARAMETERS :
3526 *   @channelHandle : channel handle
3527 *
3528 * RETURN     : a channel obj if found, NULL if not found
3529 *==========================================================================*/
3530QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
3531{
3532    for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
3533        if (m_channels[i] != NULL &&
3534            m_channels[i]->getMyHandle() == channelHandle) {
3535            return m_channels[i];
3536        }
3537    }
3538
3539    return NULL;
3540}
3541
3542/*===========================================================================
3543 * FUNCTION   : processFaceDetectionReuslt
3544 *
3545 * DESCRIPTION: process face detection reuslt
3546 *
3547 * PARAMETERS :
3548 *   @fd_data : ptr to face detection result struct
3549 *
3550 * RETURN     : int32_t type of status
3551 *              NO_ERROR  -- success
3552 *              none-zero failure code
3553 *==========================================================================*/
3554int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_face_detection_data_t *fd_data)
3555{
3556    if (!mParameters.isFaceDetectionEnabled()) {
3557        ALOGD("%s: FaceDetection not enabled, no ops here", __func__);
3558        return NO_ERROR;
3559    }
3560
3561    if ((NULL == mDataCb) || (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_METADATA) == 0)) {
3562        ALOGD("%s: prevew metadata msgtype not enabled, no ops here", __func__);
3563        return NO_ERROR;
3564    }
3565
3566    cam_dimension_t display_dim;
3567    mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
3568    if (display_dim.width <= 0 || display_dim.height <= 0) {
3569        ALOGE("%s: Invalid preview width or height (%d x %d)",
3570              __func__, display_dim.width, display_dim.height);
3571        return UNKNOWN_ERROR;
3572    }
3573
3574    // process face detection result
3575    size_t faceResultSize = sizeof(camera_frame_metadata_t);
3576    faceResultSize += sizeof(camera_face_t) * MAX_ROI;
3577    camera_memory_t *faceResultBuffer = mGetMemory(-1,
3578                                                   faceResultSize,
3579                                                   1,
3580                                                   mCallbackCookie);
3581    if ( NULL == faceResultBuffer ) {
3582        ALOGE("%s: Not enough memory for face result data",
3583              __func__);
3584        return NO_MEMORY;
3585    }
3586
3587    unsigned char *faceData = ( unsigned char * ) faceResultBuffer->data;
3588    memset(faceData, 0, faceResultSize);
3589    camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
3590    camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
3591
3592    roiData->number_of_faces = fd_data->num_faces_detected;
3593    roiData->faces = faces;
3594    if (roiData->number_of_faces > 0) {
3595        for (int i = 0; i < roiData->number_of_faces; i++) {
3596            faces[i].id = fd_data->faces[i].face_id;
3597            faces[i].score = fd_data->faces[i].score;
3598
3599            // left
3600            faces[i].rect[0] =
3601                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.left, display_dim.width, 2000, -1000);
3602
3603            // top
3604            faces[i].rect[1] =
3605                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.top, display_dim.height, 2000, -1000);
3606
3607            // right
3608            faces[i].rect[2] = faces[i].rect[0] +
3609                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.width, display_dim.width, 2000, 0);
3610
3611             // bottom
3612            faces[i].rect[3] = faces[i].rect[1] +
3613                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].face_boundary.height, display_dim.height, 2000, 0);
3614
3615            // Center of left eye
3616            faces[i].left_eye[0] =
3617                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.x, display_dim.width, 2000, -1000);
3618
3619            faces[i].left_eye[1] =
3620                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].left_eye_center.y, display_dim.height, 2000, -1000);
3621
3622            // Center of right eye
3623            faces[i].right_eye[0] =
3624                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.x, display_dim.width, 2000, -1000);
3625
3626            faces[i].right_eye[1] =
3627                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].right_eye_center.y, display_dim.height, 2000, -1000);
3628
3629            // Center of mouth
3630            faces[i].mouth[0] =
3631                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.x, display_dim.width, 2000, -1000);
3632
3633            faces[i].mouth[1] =
3634                MAP_TO_DRIVER_COORDINATE(fd_data->faces[i].mouth_center.y, display_dim.height, 2000, -1000);
3635
3636#if 0
3637            faces[i].smile_degree = fd_data->faces[i].smile_degree;
3638            faces[i].smile_score = fd_data->faces[i].smile_confidence;
3639            faces[i].blink_detected = fd_data->faces[i].blink_detected;
3640            faces[i].face_recognised = fd_data->faces[i].face_recognised;
3641            faces[i].gaze_angle = fd_data->faces[i].gaze_angle;
3642
3643            // upscale by 2 to recover from demaen downscaling
3644            faces[i].updown_dir = fd_data->faces[i].updown_dir * 2;
3645            faces[i].leftright_dir = fd_data->faces[i].leftright_dir * 2;
3646            faces[i].roll_dir = fd_data->faces[i].roll_dir * 2;
3647
3648            faces[i].leye_blink = fd_data->faces[i].left_blink;
3649            faces[i].reye_blink = fd_data->faces[i].right_blink;
3650            faces[i].left_right_gaze = fd_data->faces[i].left_right_gaze;
3651            faces[i].top_bottom_gaze = fd_data->faces[i].top_bottom_gaze;
3652#endif
3653
3654        }
3655    }
3656
3657    qcamera_callback_argm_t cbArg;
3658    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
3659    cbArg.cb_type = QCAMERA_DATA_CALLBACK;
3660    cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
3661    cbArg.data = faceResultBuffer;
3662    cbArg.metadata = roiData;
3663    cbArg.user_data = faceResultBuffer;
3664    cbArg.cookie = this;
3665    cbArg.release_cb = releaseCameraMemory;
3666    m_cbNotifier.notifyCallback(cbArg);
3667
3668    return NO_ERROR;
3669}
3670
3671/*===========================================================================
3672 * FUNCTION   : releaseCameraMemory
3673 *
3674 * DESCRIPTION: releases camera memory objects
3675 *
3676 * PARAMETERS :
3677 *   @data    : buffer to be released
3678 *   @cookie  : context data
3679 *
3680 * RETURN     : None
3681 *==========================================================================*/
3682void QCamera2HardwareInterface::releaseCameraMemory(void *data, void */*cookie*/)
3683{
3684    camera_memory_t *mem = ( camera_memory_t * ) data;
3685    if ( NULL != mem ) {
3686        mem->release(mem);
3687    }
3688}
3689
3690/*===========================================================================
3691 * FUNCTION   : returnStreamBuffer
3692 *
3693 * DESCRIPTION: returns back a stream buffer
3694 *
3695 * PARAMETERS :
3696 *   @data    : buffer to be released
3697 *   @cookie  : context data
3698 *
3699 * RETURN     : None
3700 *==========================================================================*/
3701void QCamera2HardwareInterface::returnStreamBuffer(void *data, void *cookie)
3702{
3703    QCameraStream *stream = ( QCameraStream * ) cookie;
3704    int idx = ( int ) data;
3705    if ( ( NULL != stream )) {
3706        stream->bufDone(idx);
3707    }
3708}
3709
3710/*===========================================================================
3711 * FUNCTION   : processHistogramStats
3712 *
3713 * DESCRIPTION: process histogram stats
3714 *
3715 * PARAMETERS :
3716 *   @hist_data : ptr to histogram stats struct
3717 *
3718 * RETURN     : int32_t type of status
3719 *              NO_ERROR  -- success
3720 *              none-zero failure code
3721 *==========================================================================*/
3722int32_t QCamera2HardwareInterface::processHistogramStats(cam_hist_stats_t &/*stats_data*/)
3723{
3724    if (!mParameters.isHistogramEnabled()) {
3725        ALOGD("%s: Histogram not enabled, no ops here", __func__);
3726        return NO_ERROR;
3727    }
3728
3729    camera_memory_t *histBuffer = mGetMemory(-1,
3730                                             sizeof(cam_histogram_data_t),
3731                                             1,
3732                                             mCallbackCookie);
3733    if ( NULL == histBuffer ) {
3734        ALOGE("%s: Not enough memory for histogram data",
3735              __func__);
3736        return NO_MEMORY;
3737    }
3738
3739    cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
3740    if (pHistData == NULL) {
3741        ALOGE("%s: memory data ptr is NULL", __func__);
3742        return UNKNOWN_ERROR;
3743    }
3744
3745
3746    return NO_ERROR;
3747}
3748
3749/*===========================================================================
3750 * FUNCTION   : updateThermalLevel
3751 *
3752 * DESCRIPTION: update thermal level depending on thermal events
3753 *
3754 * PARAMETERS :
3755 *   @level   : thermal level
3756 *
3757 * RETURN     : int32_t type of status
3758 *              NO_ERROR  -- success
3759 *              none-zero failure code
3760 *==========================================================================*/
3761int QCamera2HardwareInterface::updateThermalLevel(
3762            qcamera_thermal_level_enum_t level)
3763{
3764    int ret = NO_ERROR;
3765    cam_fps_range_t adjustedRange;
3766    int minFPS, maxFPS;
3767    qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
3768    enum msm_vfe_frame_skip_pattern skipPattern;
3769
3770    mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3771
3772    switch(level) {
3773    case QCAMERA_THERMAL_NO_ADJUSTMENT:
3774        {
3775            adjustedRange.min_fps = minFPS / 1000.0f;
3776            adjustedRange.max_fps = maxFPS / 1000.0f;
3777            skipPattern = NO_SKIP;
3778        }
3779        break;
3780    case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
3781        {
3782            adjustedRange.min_fps = (minFPS / 2) / 1000.0f;
3783            adjustedRange.max_fps = (maxFPS / 2) / 1000.0f;
3784            if ( adjustedRange.min_fps < 1 ) {
3785                adjustedRange.min_fps = 1;
3786            }
3787            if ( adjustedRange.max_fps < 1 ) {
3788                adjustedRange.max_fps = 1;
3789            }
3790            skipPattern = EVERY_2FRAME;
3791        }
3792        break;
3793    case QCAMERA_THERMAL_BIG_ADJUSTMENT:
3794        {
3795            adjustedRange.min_fps = (minFPS / 4) / 1000.0f;
3796            adjustedRange.max_fps = (maxFPS / 4) / 1000.0f;
3797            if ( adjustedRange.min_fps < 1 ) {
3798                adjustedRange.min_fps = 1;
3799            }
3800            if ( adjustedRange.max_fps < 1 ) {
3801                adjustedRange.max_fps = 1;
3802            }
3803            skipPattern = EVERY_4FRAME;
3804        }
3805        break;
3806    case QCAMERA_THERMAL_SHUTDOWN:
3807        {
3808            // Stop Preview?
3809            // Set lowest min FPS for now
3810            adjustedRange.min_fps = minFPS/1000.0f;
3811            adjustedRange.max_fps = minFPS/1000.0f;
3812            for ( int i = 0 ; i < gCamCapability[mCameraId]->fps_ranges_tbl_cnt ; i++ ) {
3813                if ( gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps < adjustedRange.min_fps ) {
3814                    adjustedRange.min_fps = gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
3815                    adjustedRange.max_fps = adjustedRange.min_fps;
3816                }
3817            }
3818            skipPattern = MAX_SKIP;
3819        }
3820        break;
3821    default:
3822        {
3823            ALOGE("%s: Invalid thermal level %d", __func__, level);
3824            return BAD_VALUE;
3825        }
3826        break;
3827    }
3828
3829    ALOGI("%s: Thermal level %d, FPS range [%3.2f,%3.2f], frameskip %d",
3830          __func__,
3831          level,
3832          adjustedRange.min_fps,
3833          adjustedRange.max_fps,
3834          skipPattern);
3835
3836    if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
3837        ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
3838    else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
3839        ret = mParameters.setFrameSkip(skipPattern);
3840    else
3841        ALOGE("%s: Incorrect thermal mode %d", __func__, thermalMode);
3842
3843    return ret;
3844
3845}
3846
3847/*===========================================================================
3848 * FUNCTION   : updateParameters
3849 *
3850 * DESCRIPTION: update parameters
3851 *
3852 * PARAMETERS :
3853 *   @parms       : input parameters string
3854 *   @needRestart : output, flag to indicate if preview restart is needed
3855 *
3856 * RETURN     : int32_t type of status
3857 *              NO_ERROR  -- success
3858 *              none-zero failure code
3859 *==========================================================================*/
3860int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
3861{
3862    String8 str = String8(parms);
3863    QCameraParameters param(str);
3864    return mParameters.updateParameters(param, needRestart);
3865}
3866
3867/*===========================================================================
3868 * FUNCTION   : commitParameterChanges
3869 *
3870 * DESCRIPTION: commit parameter changes to the backend to take effect
3871 *
3872 * PARAMETERS : none
3873 *
3874 * RETURN     : int32_t type of status
3875 *              NO_ERROR  -- success
3876 *              none-zero failure code
3877 * NOTE       : This function must be called after updateParameters.
3878 *              Otherwise, no change will be passed to backend to take effect.
3879 *==========================================================================*/
3880int QCamera2HardwareInterface::commitParameterChanges()
3881{
3882    int rc = mParameters.commitParameters();
3883    if (rc == NO_ERROR) {
3884        // update number of snapshot based on committed parameters setting
3885        rc = mParameters.setNumOfSnapshot();
3886    }
3887    return rc;
3888}
3889
3890/*===========================================================================
3891 * FUNCTION   : needDebugFps
3892 *
3893 * DESCRIPTION: if fps log info need to be printed out
3894 *
3895 * PARAMETERS : none
3896 *
3897 * RETURN     : true: need print out fps log
3898 *              false: no need to print out fps log
3899 *==========================================================================*/
3900bool QCamera2HardwareInterface::needDebugFps()
3901{
3902    return mParameters.isFpsDebugEnabled();
3903}
3904
3905/*===========================================================================
3906 * FUNCTION   : isCACEnabled
3907 *
3908 * DESCRIPTION: if CAC is enabled
3909 *
3910 * PARAMETERS : none
3911 *
3912 * RETURN     : true: needed
3913 *              false: no need
3914 *==========================================================================*/
3915bool QCamera2HardwareInterface::isCACEnabled()
3916{
3917    char prop[PROPERTY_VALUE_MAX];
3918    memset(prop, 0, sizeof(prop));
3919    property_get("persist.camera.feature.cac", prop, "0");
3920    int enableCAC = atoi(prop);
3921    return enableCAC == 1;
3922}
3923
3924/*===========================================================================
3925 * FUNCTION   : needReprocess
3926 *
3927 * DESCRIPTION: if reprocess is needed
3928 *
3929 * PARAMETERS : none
3930 *
3931 * RETURN     : true: needed
3932 *              false: no need
3933 *==========================================================================*/
3934bool QCamera2HardwareInterface::needReprocess()
3935{
3936    if (!mParameters.isJpegPictureFormat()) {
3937        // RAW image, no need to reprocess
3938        return false;
3939    }
3940
3941    if (((gCamCapability[mCameraId]->min_required_pp_mask > 0) ||
3942         mParameters.isWNREnabled() || isCACEnabled())) {
3943        // TODO: add for ZSL HDR later
3944        ALOGD("%s: need do reprocess for ZSL WNR or min PP reprocess", __func__);
3945        return true;
3946    }
3947
3948    return needRotationReprocess();
3949}
3950
3951/*===========================================================================
3952 * FUNCTION   : needRotationReprocess
3953 *
3954 * DESCRIPTION: if rotation needs to be done by reprocess in pp
3955 *
3956 * PARAMETERS : none
3957 *
3958 * RETURN     : true: needed
3959 *              false: no need
3960 *==========================================================================*/
3961bool QCamera2HardwareInterface::needRotationReprocess()
3962{
3963    if (!mParameters.isJpegPictureFormat()) {
3964        // RAW image, no need to reprocess
3965        return false;
3966    }
3967
3968    if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
3969        mParameters.getJpegRotation() > 0) {
3970        // current rotation is not zero, and pp has the capability to process rotation
3971        ALOGD("%s: need do reprocess for rotation", __func__);
3972        return true;
3973    }
3974
3975    return false;
3976}
3977
3978/*===========================================================================
3979 * FUNCTION   : getThumbnailSize
3980 *
3981 * DESCRIPTION: get user set thumbnail size
3982 *
3983 * PARAMETERS :
3984 *   @dim     : output of thumbnail dimension
3985 *
3986 * RETURN     : none
3987 *==========================================================================*/
3988void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
3989{
3990    mParameters.getThumbnailSize(&dim.width, &dim.height);
3991}
3992
3993/*===========================================================================
3994 * FUNCTION   : getJpegQuality
3995 *
3996 * DESCRIPTION: get user set jpeg quality
3997 *
3998 * PARAMETERS : none
3999 *
4000 * RETURN     : jpeg quality setting
4001 *==========================================================================*/
4002int QCamera2HardwareInterface::getJpegQuality()
4003{
4004    return mParameters.getJpegQuality();
4005}
4006
4007/*===========================================================================
4008 * FUNCTION   : getJpegRotation
4009 *
4010 * DESCRIPTION: get rotation information to be passed into jpeg encoding
4011 *
4012 * PARAMETERS : none
4013 *
4014 * RETURN     : rotation information
4015 *==========================================================================*/
4016int QCamera2HardwareInterface::getJpegRotation() {
4017    return mParameters.getJpegRotation();
4018}
4019
4020/*===========================================================================
4021 * FUNCTION   : getExifData
4022 *
4023 * DESCRIPTION: get exif data to be passed into jpeg encoding
4024 *
4025 * PARAMETERS : none
4026 *
4027 * RETURN     : exif data from user setting and GPS
4028 *==========================================================================*/
4029QCameraExif *QCamera2HardwareInterface::getExifData()
4030{
4031    QCameraExif *exif = new QCameraExif();
4032    if (exif == NULL) {
4033        ALOGE("%s: No memory for QCameraExif", __func__);
4034        return NULL;
4035    }
4036
4037    int32_t rc = NO_ERROR;
4038    uint32_t count = 0;
4039
4040    // add exif entries
4041    char dateTime[20];
4042    memset(dateTime, 0, sizeof(dateTime));
4043    count = 20;
4044    rc = mParameters.getExifDateTime(dateTime, count);
4045    if(rc == NO_ERROR) {
4046        exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL,
4047                       EXIF_ASCII,
4048                       count,
4049                       (void *)dateTime);
4050    } else {
4051        ALOGE("%s: getExifDateTime failed", __func__);
4052    }
4053
4054    rat_t focalLength;
4055    rc = mParameters.getExifFocalLength(&focalLength);
4056    if (rc == NO_ERROR) {
4057        exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
4058                       EXIF_RATIONAL,
4059                       1,
4060                       (void *)&(focalLength));
4061    } else {
4062        ALOGE("%s: getExifFocalLength failed", __func__);
4063    }
4064
4065    uint16_t isoSpeed = mParameters.getExifIsoSpeed();
4066    exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
4067                   EXIF_SHORT,
4068                   1,
4069                   (void *)&(isoSpeed));
4070
4071    char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
4072    count = 0;
4073    rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
4074    if(rc == NO_ERROR) {
4075        exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
4076                       EXIF_ASCII,
4077                       count,
4078                       (void *)gpsProcessingMethod);
4079    } else {
4080        ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
4081    }
4082
4083    rat_t latitude[3];
4084    char latRef[2];
4085    rc = mParameters.getExifLatitude(latitude, latRef);
4086    if(rc == NO_ERROR) {
4087        exif->addEntry(EXIFTAGID_GPS_LATITUDE,
4088                       EXIF_RATIONAL,
4089                       3,
4090                       (void *)latitude);
4091        exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
4092                       EXIF_ASCII,
4093                       2,
4094                       (void *)latRef);
4095    } else {
4096        ALOGE("%s: getExifLatitude failed", __func__);
4097    }
4098
4099    rat_t longitude[3];
4100    char lonRef[2];
4101    rc = mParameters.getExifLongitude(longitude, lonRef);
4102    if(rc == NO_ERROR) {
4103        exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
4104                       EXIF_RATIONAL,
4105                       3,
4106                       (void *)longitude);
4107
4108        exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
4109                       EXIF_ASCII,
4110                       2,
4111                       (void *)lonRef);
4112    } else {
4113        ALOGE("%s: getExifLongitude failed", __func__);
4114    }
4115
4116    rat_t altitude;
4117    char altRef;
4118    rc = mParameters.getExifAltitude(&altitude, &altRef);
4119    if(rc == NO_ERROR) {
4120        exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
4121                       EXIF_RATIONAL,
4122                       1,
4123                       (void *)&(altitude));
4124
4125        exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
4126                       EXIF_BYTE,
4127                       1,
4128                       (void *)&altRef);
4129    } else {
4130        ALOGE("%s: getExifAltitude failed", __func__);
4131    }
4132
4133    char gpsDateStamp[20];
4134    rat_t gpsTimeStamp[3];
4135    rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
4136    if(rc == NO_ERROR) {
4137        exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
4138                       EXIF_ASCII,
4139                       strlen(gpsDateStamp) + 1,
4140                       (void *)gpsDateStamp);
4141
4142        exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
4143                       EXIF_RATIONAL,
4144                       3,
4145                       (void *)gpsTimeStamp);
4146    } else {
4147        ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
4148    }
4149
4150    char value[PROPERTY_VALUE_MAX];
4151    if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
4152        exif->addEntry(EXIFTAGID_MAKE,
4153                       EXIF_ASCII,
4154                       strlen(value) + 1,
4155                       (void *)value);
4156    } else {
4157        ALOGE("%s: getExifMaker failed", __func__);
4158    }
4159
4160    if (property_get("ro.product.model", value, "QCAM-AA") > 0) {
4161        exif->addEntry(EXIFTAGID_MODEL,
4162                       EXIF_ASCII,
4163                       strlen(value) + 1,
4164                       (void *)value);
4165    } else {
4166        ALOGE("%s: getExifModel failed", __func__);
4167    }
4168
4169    return exif;
4170}
4171
4172/*===========================================================================
4173 * FUNCTION   : setHistogram
4174 *
4175 * DESCRIPTION: set if histogram should be enabled
4176 *
4177 * PARAMETERS :
4178 *   @histogram_en : bool flag if histogram should be enabled
4179 *
4180 * RETURN     : int32_t type of status
4181 *              NO_ERROR  -- success
4182 *              none-zero failure code
4183 *==========================================================================*/
4184int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
4185{
4186    return mParameters.setHistogram(histogram_en);
4187}
4188
4189/*===========================================================================
4190 * FUNCTION   : setFaceDetection
4191 *
4192 * DESCRIPTION: set if face detection should be enabled
4193 *
4194 * PARAMETERS :
4195 *   @enabled : bool flag if face detection should be enabled
4196 *
4197 * RETURN     : int32_t type of status
4198 *              NO_ERROR  -- success
4199 *              none-zero failure code
4200 *==========================================================================*/
4201int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
4202{
4203    return mParameters.setFaceDetection(enabled);
4204}
4205
4206/*===========================================================================
4207 * FUNCTION   : prepareHardwareForSnapshot
4208 *
4209 * DESCRIPTION: prepare hardware for snapshot, such as LED
4210 *
4211 * PARAMETERS :
4212 *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
4213 *
4214 * RETURN     : int32_t type of status
4215 *              NO_ERROR  -- success
4216 *              none-zero failure code
4217 *==========================================================================*/
4218int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
4219{
4220    ALOGD("[KPI Perf] %s: Prepare hardware such as LED",__func__);
4221    return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
4222                                                afNeeded);
4223}
4224
4225}; // namespace qcamera
4226