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