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