Home | History | Annotate | Download | only in HAL
      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 
     46 namespace qcamera {
     47 
     48 cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
     49 static pthread_mutex_t g_camlock = PTHREAD_MUTEX_INITIALIZER;
     50 
     51 camera_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  *==========================================================================*/
     96 int 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  *==========================================================================*/
    133 void 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  *==========================================================================*/
    173 void 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  *==========================================================================*/
    200 void 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  *==========================================================================*/
    228 int 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  *==========================================================================*/
    260 int 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  *==========================================================================*/
    295 void 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  *==========================================================================*/
    324 int 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  *==========================================================================*/
    358 int 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  *==========================================================================*/
    392 int 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  *==========================================================================*/
    423 void 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  *==========================================================================*/
    452 int 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  *==========================================================================*/
    483 void 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  *==========================================================================*/
    514 int 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  *==========================================================================*/
    548 int 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  *==========================================================================*/
    580 int 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  *==========================================================================*/
    627 int 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  *==========================================================================*/
    660 int 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  *==========================================================================*/
    691 char* 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  *==========================================================================*/
    722 void 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  *==========================================================================*/
    754 int 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  *==========================================================================*/
    793 void 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  *==========================================================================*/
    822 int 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  *==========================================================================*/
    854 int 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  *==========================================================================*/
    884 int 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  *==========================================================================*/
    920 QCamera2HardwareInterface::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  *==========================================================================*/
    972 QCamera2HardwareInterface::~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  *==========================================================================*/
    993 int 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  *==========================================================================*/
   1020 int 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  *==========================================================================*/
   1078 int 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  *==========================================================================*/
   1122 int 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 
   1170 query_failed:
   1171     cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
   1172                             CAM_MAPPING_BUF_TYPE_CAPABILITY);
   1173 map_failed:
   1174     capabilityHeap->deallocate();
   1175     delete capabilityHeap;
   1176 allocate_failed:
   1177     cameraHandle->ops->close_camera(cameraHandle->camera_handle);
   1178     cameraHandle = NULL;
   1179 open_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  *==========================================================================*/
   1196 int 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  *==========================================================================*/
   1240 uint8_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  *==========================================================================*/
   1347 QCameraMemory *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  *==========================================================================*/
   1436 QCameraHeapMemory *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  *==========================================================================*/
   1502 int 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  *==========================================================================*/
   1525 int 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  *==========================================================================*/
   1552 int 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  *==========================================================================*/
   1570 int 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  *==========================================================================*/
   1587 int 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  *==========================================================================*/
   1603 int 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  *==========================================================================*/
   1623 int 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  *==========================================================================*/
   1648 int 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  *==========================================================================*/
   1676 int 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  *==========================================================================*/
   1693 int 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  *==========================================================================*/
   1738 int 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  *==========================================================================*/
   1765 int 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  *==========================================================================*/
   1788 int 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  *==========================================================================*/
   1861 int 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  *==========================================================================*/
   1905 int 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  *==========================================================================*/
   1986 int 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  *==========================================================================*/
   2027 int 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  *==========================================================================*/
   2052 int 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  *==========================================================================*/
   2074 char* 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  *==========================================================================*/
   2100 int 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  *==========================================================================*/
   2120 int 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  *==========================================================================*/
   2150 int 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  *==========================================================================*/
   2231 int 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  *==========================================================================*/
   2256 int 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  *==========================================================================*/
   2275 int 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  *==========================================================================*/
   2293 int 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  *==========================================================================*/
   2311 int 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  *==========================================================================*/
   2341 void 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  *==========================================================================*/
   2372 void 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  *==========================================================================*/
   2410 int 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  *==========================================================================*/
   2436 int32_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  *==========================================================================*/
   2461 int32_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  *==========================================================================*/
   2530 int32_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  *==========================================================================*/
   2555 int32_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  *==========================================================================*/
   2587 int32_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  *==========================================================================*/
   2601 void 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  *==========================================================================*/
   2617 void 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  *==========================================================================*/
   2637 void 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  *==========================================================================*/
   2652 void 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  *==========================================================================*/
   2670 void 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  *==========================================================================*/
   2693 int32_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  *==========================================================================*/
   2732 int32_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  *==========================================================================*/
   2795 int32_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  *==========================================================================*/
   2846 int32_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  *==========================================================================*/
   2894 int32_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  *==========================================================================*/
   2952 int32_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  *==========================================================================*/
   3035 int32_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  *==========================================================================*/
   3109 int32_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  *==========================================================================*/
   3158 QCameraReprocessChannel *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  *==========================================================================*/
   3250 QCameraReprocessChannel *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  *==========================================================================*/
   3321 int32_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  *==========================================================================*/
   3364 int32_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  *==========================================================================*/
   3386 int32_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  *==========================================================================*/
   3408 int32_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  *==========================================================================*/
   3429 int32_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  *==========================================================================*/
   3476 void 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  *==========================================================================*/
   3498 void 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  *==========================================================================*/
   3530 QCameraChannel *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  *==========================================================================*/
   3554 int32_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  *==========================================================================*/
   3682 void 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  *==========================================================================*/
   3701 void 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  *==========================================================================*/
   3722 int32_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  *==========================================================================*/
   3761 int 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  *==========================================================================*/
   3860 int 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  *==========================================================================*/
   3880 int 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  *==========================================================================*/
   3900 bool 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  *==========================================================================*/
   3915 bool 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  *==========================================================================*/
   3934 bool 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  *==========================================================================*/
   3961 bool 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  *==========================================================================*/
   3988 void 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  *==========================================================================*/
   4002 int 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  *==========================================================================*/
   4016 int 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  *==========================================================================*/
   4029 QCameraExif *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  *==========================================================================*/
   4184 int32_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  *==========================================================================*/
   4201 int32_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  *==========================================================================*/
   4218 int32_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