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