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