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