Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2017, The Linux Foundation. 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 // To remove
     33 #include <cutils/properties.h>
     34 
     35 // System definitions
     36 #include <utils/Errors.h>
     37 #include <dlfcn.h>
     38 #include <stdio.h>
     39 #include <stdlib.h>
     40 #include "gralloc_priv.h"
     41 #include "native_handle.h"
     42 
     43 // Camera definitions
     44 #include "android/QCamera2External.h"
     45 #include "QCamera2HWI.h"
     46 #include "QCameraBufferMaps.h"
     47 #include "QCameraFlash.h"
     48 #include "QCameraTrace.h"
     49 
     50 extern "C" {
     51 #include "mm_camera_dbg.h"
     52 }
     53 
     54 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \
     55     ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset)
     56 #define CAMERA_MIN_STREAMING_BUFFERS     3
     57 #define EXTRA_ZSL_PREVIEW_STREAM_BUF     2
     58 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
     59 #define CAMERA_MIN_VIDEO_BUFFERS         9
     60 #define CAMERA_MIN_CALLBACK_BUFFERS      5
     61 #define CAMERA_LONGSHOT_STAGES           4
     62 #define CAMERA_MIN_CAMERA_BATCH_BUFFERS  6
     63 #define CAMERA_ISP_PING_PONG_BUFFERS     2
     64 #define MIN_UNDEQUEUED_BUFFERS           1 // This is required if preview window is not set
     65 #define CAMERA_MIN_DISPLAY_BUFFERS       2
     66 #define CAMERA_DEFAULT_FPS               30000
     67 
     68 #define HDR_CONFIDENCE_THRESHOLD 0.4
     69 
     70 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds
     71 
     72 // Very long wait, just to be sure we don't deadlock
     73 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
     74 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
     75 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
     76 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
     77 #define CAMERA_MAX_PARAM_APPLY_DELAY 3
     78 
     79 namespace qcamera {
     80 
     81 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
     82 extern pthread_mutex_t gCamLock;
     83 volatile uint32_t gCamHalLogLevel = 1;
     84 extern uint8_t gNumCameraSessions;
     85 uint32_t QCamera2HardwareInterface::sNextJobId = 1;
     86 
     87 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
     88     .set_preview_window =        QCamera2HardwareInterface::set_preview_window,
     89     .set_callbacks =             QCamera2HardwareInterface::set_CallBacks,
     90     .enable_msg_type =           QCamera2HardwareInterface::enable_msg_type,
     91     .disable_msg_type =          QCamera2HardwareInterface::disable_msg_type,
     92     .msg_type_enabled =          QCamera2HardwareInterface::msg_type_enabled,
     93 
     94     .start_preview =             QCamera2HardwareInterface::start_preview,
     95     .stop_preview =              QCamera2HardwareInterface::stop_preview,
     96     .preview_enabled =           QCamera2HardwareInterface::preview_enabled,
     97     .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,
     98 
     99     .start_recording =           QCamera2HardwareInterface::start_recording,
    100     .stop_recording =            QCamera2HardwareInterface::stop_recording,
    101     .recording_enabled =         QCamera2HardwareInterface::recording_enabled,
    102     .release_recording_frame =   QCamera2HardwareInterface::release_recording_frame,
    103 
    104     .auto_focus =                QCamera2HardwareInterface::auto_focus,
    105     .cancel_auto_focus =         QCamera2HardwareInterface::cancel_auto_focus,
    106 
    107     .take_picture =              QCamera2HardwareInterface::take_picture,
    108     .cancel_picture =            QCamera2HardwareInterface::cancel_picture,
    109 
    110     .set_parameters =            QCamera2HardwareInterface::set_parameters,
    111     .get_parameters =            QCamera2HardwareInterface::get_parameters,
    112     .put_parameters =            QCamera2HardwareInterface::put_parameters,
    113     .send_command =              QCamera2HardwareInterface::send_command,
    114 
    115     .release =                   QCamera2HardwareInterface::release,
    116     .dump =                      QCamera2HardwareInterface::dump,
    117 };
    118 
    119 /*===========================================================================
    120  * FUNCTION   : set_preview_window
    121  *
    122  * DESCRIPTION: set preview window.
    123  *
    124  * PARAMETERS :
    125  *   @device  : ptr to camera device struct
    126  *   @window  : window ops table
    127  *
    128  * RETURN     : int32_t type of status
    129  *              NO_ERROR  -- success
    130  *              none-zero failure code
    131  *==========================================================================*/
    132 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
    133         struct preview_stream_ops *window)
    134 {
    135     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PREVIEW_WINDOW);
    136     int rc = NO_ERROR;
    137     QCamera2HardwareInterface *hw =
    138         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    139     if (!hw) {
    140         LOGE("NULL camera device");
    141         return BAD_VALUE;
    142     }
    143     LOGD("E camera id %d window = %p", hw->getCameraId(), window);
    144 
    145     hw->lockAPI();
    146     qcamera_api_result_t apiResult;
    147     rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
    148     if (rc == NO_ERROR) {
    149         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
    150         rc = apiResult.status;
    151     }
    152     hw->unlockAPI();
    153     LOGD("X camera id %d", hw->getCameraId());
    154 
    155     return rc;
    156 }
    157 
    158 /*===========================================================================
    159  * FUNCTION   : set_CallBacks
    160  *
    161  * DESCRIPTION: set callbacks for notify and data
    162  *
    163  * PARAMETERS :
    164  *   @device     : ptr to camera device struct
    165  *   @notify_cb  : notify cb
    166  *   @data_cb    : data cb
    167  *   @data_cb_timestamp  : video data cd with timestamp
    168  *   @get_memory : ops table for request gralloc memory
    169  *   @user       : user data ptr
    170  *
    171  * RETURN     : none
    172  *==========================================================================*/
    173 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
    174         camera_notify_callback notify_cb,
    175         camera_data_callback data_cb,
    176         camera_data_timestamp_callback data_cb_timestamp,
    177         camera_request_memory get_memory,
    178         void *user)
    179 {
    180     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_CALLBACKS);
    181     QCamera2HardwareInterface *hw =
    182         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    183     if (!hw) {
    184         LOGE("NULL camera device");
    185         return;
    186     }
    187     LOGD("E camera id %d", hw->getCameraId());
    188 
    189     qcamera_sm_evt_setcb_payload_t payload;
    190     payload.notify_cb = notify_cb;
    191     payload.data_cb = data_cb;
    192     payload.data_cb_timestamp = data_cb_timestamp;
    193     payload.get_memory = get_memory;
    194     payload.user = user;
    195 
    196     hw->lockAPI();
    197     qcamera_api_result_t apiResult;
    198     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
    199     if (rc == NO_ERROR) {
    200         hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
    201     }
    202     hw->unlockAPI();
    203     LOGD("X camera id %d", hw->getCameraId());
    204 
    205 }
    206 
    207 /*===========================================================================
    208  * FUNCTION   : enable_msg_type
    209  *
    210  * DESCRIPTION: enable certain msg type
    211  *
    212  * PARAMETERS :
    213  *   @device     : ptr to camera device struct
    214  *   @msg_type   : msg type mask
    215  *
    216  * RETURN     : none
    217  *==========================================================================*/
    218 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
    219 {
    220     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_ENABLE_MSG_TYPE);
    221     QCamera2HardwareInterface *hw =
    222         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    223     if (!hw) {
    224         LOGE("NULL camera device");
    225         return;
    226     }
    227     LOGD("E camera id %d", hw->getCameraId());
    228 
    229     hw->lockAPI();
    230     qcamera_api_result_t apiResult;
    231     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
    232     if (rc == NO_ERROR) {
    233         hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
    234     }
    235     hw->unlockAPI();
    236     LOGD("X camera id %d", hw->getCameraId());
    237 
    238 }
    239 
    240 /*===========================================================================
    241  * FUNCTION   : disable_msg_type
    242  *
    243  * DESCRIPTION: disable certain msg type
    244  *
    245  * PARAMETERS :
    246  *   @device     : ptr to camera device struct
    247  *   @msg_type   : msg type mask
    248  *
    249  * RETURN     : none
    250  *==========================================================================*/
    251 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
    252 {
    253     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_DISABLE_MSG_TYPE);
    254     QCamera2HardwareInterface *hw =
    255         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    256     if (!hw) {
    257         LOGE("NULL camera device");
    258         return;
    259     }
    260     LOGD("E camera id %d", hw->getCameraId());
    261 
    262     hw->lockAPI();
    263     qcamera_api_result_t apiResult;
    264     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
    265     if (rc == NO_ERROR) {
    266         hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
    267     }
    268     hw->unlockAPI();
    269     LOGD("X camera id %d", hw->getCameraId());
    270 
    271 }
    272 
    273 /*===========================================================================
    274  * FUNCTION   : msg_type_enabled
    275  *
    276  * DESCRIPTION: if certain msg type is enabled
    277  *
    278  * PARAMETERS :
    279  *   @device     : ptr to camera device struct
    280  *   @msg_type   : msg type mask
    281  *
    282  * RETURN     : 1 -- enabled
    283  *              0 -- not enabled
    284  *==========================================================================*/
    285 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
    286 {
    287     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_MSG_TYPE_ENABLED);
    288     int ret = NO_ERROR;
    289     QCamera2HardwareInterface *hw =
    290         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    291     if (!hw) {
    292         LOGE("NULL camera device");
    293         return BAD_VALUE;
    294     }
    295     LOGD("E camera id %d", hw->getCameraId());
    296 
    297     hw->lockAPI();
    298     qcamera_api_result_t apiResult;
    299     ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
    300     if (ret == NO_ERROR) {
    301         hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
    302         ret = apiResult.enabled;
    303     }
    304     hw->unlockAPI();
    305     LOGD("X camera id %d", hw->getCameraId());
    306 
    307    return ret;
    308 }
    309 
    310 /*===========================================================================
    311  * FUNCTION   : prepare_preview
    312  *
    313  * DESCRIPTION: prepare preview
    314  *
    315  * PARAMETERS :
    316  *   @device  : ptr to camera device struct
    317  *
    318  * RETURN     : int32_t type of status
    319  *              NO_ERROR  -- success
    320  *              none-zero failure code
    321  *==========================================================================*/
    322 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
    323 {
    324     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_PREVIEW);
    325     int ret = NO_ERROR;
    326     QCamera2HardwareInterface *hw =
    327         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    328     if (!hw) {
    329         LOGE("NULL camera device");
    330         return BAD_VALUE;
    331     }
    332     LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
    333              hw->getCameraId());
    334     hw->lockAPI();
    335     qcamera_api_result_t apiResult;
    336     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
    337     ret = hw->processAPI(evt, NULL);
    338     if (ret == NO_ERROR) {
    339         hw->waitAPIResult(evt, &apiResult);
    340         ret = apiResult.status;
    341     }
    342     hw->unlockAPI();
    343     LOGH("[KPI Perf]: X");
    344     return ret;
    345 }
    346 
    347 
    348 /*===========================================================================
    349  * FUNCTION   : start_preview
    350  *
    351  * DESCRIPTION: start preview
    352  *
    353  * PARAMETERS :
    354  *   @device  : ptr to camera device struct
    355  *
    356  * RETURN     : int32_t type of status
    357  *              NO_ERROR  -- success
    358  *              none-zero failure code
    359  *==========================================================================*/
    360 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
    361 {
    362     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_PREVIEW);
    363     int ret = NO_ERROR;
    364     QCamera2HardwareInterface *hw =
    365         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    366     if (!hw) {
    367         LOGE("NULL camera device");
    368         return BAD_VALUE;
    369     }
    370     LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
    371              hw->getCameraId());
    372 
    373     hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
    374     hw->lockAPI();
    375     qcamera_api_result_t apiResult;
    376     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
    377     if (hw->isNoDisplayMode()) {
    378         evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
    379     }
    380     ret = hw->processAPI(evt, NULL);
    381     if (ret == NO_ERROR) {
    382         hw->waitAPIResult(evt, &apiResult);
    383         ret = apiResult.status;
    384     }
    385     hw->unlockAPI();
    386     hw->m_bPreviewStarted = true;
    387     LOGI("[KPI Perf]: X ret = %d", ret);
    388     return ret;
    389 }
    390 
    391 /*===========================================================================
    392  * FUNCTION   : stop_preview
    393  *
    394  * DESCRIPTION: stop preview
    395  *
    396  * PARAMETERS :
    397  *   @device  : ptr to camera device struct
    398  *
    399  * RETURN     : none
    400  *==========================================================================*/
    401 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
    402 {
    403     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_PREVIEW);
    404     QCamera2HardwareInterface *hw =
    405         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    406     if (!hw) {
    407         LOGE("NULL camera device");
    408         return;
    409     }
    410     LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
    411              hw->getCameraId());
    412 
    413     // Disable power Hint for preview
    414     hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
    415 
    416     hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
    417 
    418     hw->lockAPI();
    419     qcamera_api_result_t apiResult;
    420     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
    421     if (ret == NO_ERROR) {
    422         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult);
    423     }
    424     hw->unlockAPI();
    425     LOGI("[KPI Perf]: X ret = %d", ret);
    426 }
    427 
    428 /*===========================================================================
    429  * FUNCTION   : preview_enabled
    430  *
    431  * DESCRIPTION: if preview is running
    432  *
    433  * PARAMETERS :
    434  *   @device  : ptr to camera device struct
    435  *
    436  * RETURN     : 1 -- running
    437  *              0 -- not running
    438  *==========================================================================*/
    439 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
    440 {
    441     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREVIEW_ENABLED);
    442     int ret = NO_ERROR;
    443     QCamera2HardwareInterface *hw =
    444         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    445     if (!hw) {
    446         LOGE("NULL camera device");
    447         return BAD_VALUE;
    448     }
    449     LOGD("E camera id %d", hw->getCameraId());
    450 
    451     hw->lockAPI();
    452     qcamera_api_result_t apiResult;
    453     ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
    454     if (ret == NO_ERROR) {
    455         hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult);
    456         ret = apiResult.enabled;
    457     }
    458 
    459     //if preview enabled, can enable preview callback send
    460     if(apiResult.enabled) {
    461         hw->m_stateMachine.setPreviewCallbackNeeded(true);
    462     }
    463     hw->unlockAPI();
    464     LOGD("X camera id %d", hw->getCameraId());
    465 
    466     return ret;
    467 }
    468 
    469 /*===========================================================================
    470  * FUNCTION   : store_meta_data_in_buffers
    471  *
    472  * DESCRIPTION: if need to store meta data in buffers for video frame
    473  *
    474  * PARAMETERS :
    475  *   @device  : ptr to camera device struct
    476  *   @enable  : flag if enable
    477  *
    478  * RETURN     : int32_t type of status
    479  *              NO_ERROR  -- success
    480  *              none-zero failure code
    481  *==========================================================================*/
    482 int QCamera2HardwareInterface::store_meta_data_in_buffers(
    483                 struct camera_device *device, int enable)
    484 {
    485     int ret = NO_ERROR;
    486     QCamera2HardwareInterface *hw =
    487         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    488     if (!hw) {
    489         LOGE("NULL camera device");
    490         return BAD_VALUE;
    491     }
    492     LOGD("E camera id %d", hw->getCameraId());
    493 
    494     hw->lockAPI();
    495     qcamera_api_result_t apiResult;
    496     ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable);
    497     if (ret == NO_ERROR) {
    498         hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult);
    499         ret = apiResult.status;
    500     }
    501     hw->unlockAPI();
    502     LOGD("X camera id %d", hw->getCameraId());
    503 
    504     return ret;
    505 }
    506 
    507 /*===========================================================================
    508  * FUNCTION   : restart_start_preview
    509  *
    510  * DESCRIPTION: start preview as part of the restart preview
    511  *
    512  * PARAMETERS :
    513  *   @device  : ptr to camera device struct
    514  *
    515  * RETURN     : int32_t type of status
    516  *              NO_ERROR  -- success
    517  *              none-zero failure code
    518  *==========================================================================*/
    519 int QCamera2HardwareInterface::restart_start_preview(struct camera_device *device)
    520 {
    521     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_START_PREVIEW);
    522     int ret = NO_ERROR;
    523     QCamera2HardwareInterface *hw =
    524         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    525     if (!hw) {
    526         LOGE("NULL camera device");
    527         return BAD_VALUE;
    528     }
    529     LOGI("E camera id %d", hw->getCameraId());
    530     hw->lockAPI();
    531     qcamera_api_result_t apiResult;
    532 
    533     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
    534         ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_START_PREVIEW, NULL);
    535         if (ret == NO_ERROR) {
    536             hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_START_PREVIEW, &apiResult);
    537             ret = apiResult.status;
    538         }
    539     } else {
    540         LOGE("This function is not supposed to be called in single-camera mode");
    541         ret = INVALID_OPERATION;
    542     }
    543     // Preview restart done, update the mPreviewRestartNeeded flag to false.
    544     hw->mPreviewRestartNeeded = false;
    545     hw->unlockAPI();
    546     LOGI("X camera id %d", hw->getCameraId());
    547 
    548     return ret;
    549 }
    550 
    551 /*===========================================================================
    552  * FUNCTION   : restart_stop_preview
    553  *
    554  * DESCRIPTION: stop preview as part of the restart preview
    555  *
    556  * PARAMETERS :
    557  *   @device  : ptr to camera device struct
    558  *
    559  * RETURN     : int32_t type of status
    560  *              NO_ERROR  -- success
    561  *              none-zero failure code
    562  *==========================================================================*/
    563 int QCamera2HardwareInterface::restart_stop_preview(struct camera_device *device)
    564 {
    565     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_STOP_PREVIEW);
    566     int ret = NO_ERROR;
    567     QCamera2HardwareInterface *hw =
    568         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    569     if (!hw) {
    570         LOGE("NULL camera device");
    571         return BAD_VALUE;
    572     }
    573     LOGI("E camera id %d", hw->getCameraId());
    574     hw->lockAPI();
    575     qcamera_api_result_t apiResult;
    576 
    577     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
    578         ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, NULL);
    579         if (ret == NO_ERROR) {
    580             hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, &apiResult);
    581             ret = apiResult.status;
    582         }
    583     } else {
    584         LOGE("This function is not supposed to be called in single-camera mode");
    585         ret = INVALID_OPERATION;
    586     }
    587 
    588     hw->unlockAPI();
    589     LOGI("X camera id %d", hw->getCameraId());
    590 
    591     return ret;
    592 }
    593 
    594 /*===========================================================================
    595  * FUNCTION   : pre_start_recording
    596  *
    597  * DESCRIPTION: prepare for the start recording
    598  *
    599  * PARAMETERS :
    600  *   @device  : ptr to camera device struct
    601  *
    602  * RETURN     : int32_t type of status
    603  *              NO_ERROR  -- success
    604  *              none-zero failure code
    605  *==========================================================================*/
    606 int QCamera2HardwareInterface::pre_start_recording(struct camera_device *device)
    607 {
    608     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_START_RECORDING);
    609     int ret = NO_ERROR;
    610     QCamera2HardwareInterface *hw =
    611         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    612     if (!hw) {
    613         LOGE("NULL camera device");
    614         return BAD_VALUE;
    615     }
    616     LOGH("[KPI Perf]: E PROFILE_PRE_START_RECORDING camera id %d",
    617           hw->getCameraId());
    618     hw->lockAPI();
    619     qcamera_api_result_t apiResult;
    620     ret = hw->processAPI(QCAMERA_SM_EVT_PRE_START_RECORDING, NULL);
    621     if (ret == NO_ERROR) {
    622         hw->waitAPIResult(QCAMERA_SM_EVT_PRE_START_RECORDING, &apiResult);
    623         ret = apiResult.status;
    624     }
    625     hw->unlockAPI();
    626     LOGH("[KPI Perf]: X");
    627     return ret;
    628 }
    629 
    630 /*===========================================================================
    631  * FUNCTION   : start_recording
    632  *
    633  * DESCRIPTION: start recording
    634  *
    635  * PARAMETERS :
    636  *   @device  : ptr to camera device struct
    637  *
    638  * RETURN     : int32_t type of status
    639  *              NO_ERROR  -- success
    640  *              none-zero failure code
    641  *==========================================================================*/
    642 int QCamera2HardwareInterface::start_recording(struct camera_device *device)
    643 {
    644     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_RECORDING);
    645     int ret = NO_ERROR;
    646     QCamera2HardwareInterface *hw =
    647         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    648     if (!hw) {
    649         LOGE("NULL camera device");
    650         return BAD_VALUE;
    651     }
    652 
    653     hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
    654 
    655     LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
    656           hw->getCameraId());
    657     // Give HWI control to call pre_start_recording in single camera mode.
    658     // In dual-cam mode, this control belongs to muxer.
    659     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    660         ret = pre_start_recording(device);
    661         if (ret != NO_ERROR) {
    662             LOGE("pre_start_recording failed with ret = %d", ret);
    663             hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
    664             return ret;
    665         }
    666     }
    667 
    668     hw->lockAPI();
    669     qcamera_api_result_t apiResult;
    670     ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
    671     if (ret == NO_ERROR) {
    672         hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
    673         ret = apiResult.status;
    674     }
    675     hw->unlockAPI();
    676     hw->m_bRecordStarted = true;
    677     LOGI("[KPI Perf]: X ret = %d", ret);
    678 
    679     return ret;
    680 }
    681 
    682 /*===========================================================================
    683  * FUNCTION   : stop_recording
    684  *
    685  * DESCRIPTION: stop recording
    686  *
    687  * PARAMETERS :
    688  *   @device  : ptr to camera device struct
    689  *
    690  * RETURN     : none
    691  *==========================================================================*/
    692 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
    693 {
    694     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_RECORDING);
    695     QCamera2HardwareInterface *hw =
    696         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    697     if (!hw) {
    698         LOGE("NULL camera device");
    699         return;
    700     }
    701 
    702     hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
    703 
    704     LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
    705              hw->getCameraId());
    706 
    707     hw->lockAPI();
    708     qcamera_api_result_t apiResult;
    709     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
    710     if (ret == NO_ERROR) {
    711         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
    712     }
    713     hw->unlockAPI();
    714     LOGI("[KPI Perf]: X ret = %d", ret);
    715 }
    716 
    717 /*===========================================================================
    718  * FUNCTION   : recording_enabled
    719  *
    720  * DESCRIPTION: if recording is running
    721  *
    722  * PARAMETERS :
    723  *   @device  : ptr to camera device struct
    724  *
    725  * RETURN     : 1 -- running
    726  *              0 -- not running
    727  *==========================================================================*/
    728 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
    729 {
    730     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RECORDING_ENABLED);
    731     int ret = NO_ERROR;
    732     QCamera2HardwareInterface *hw =
    733         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    734     if (!hw) {
    735         LOGE("NULL camera device");
    736         return BAD_VALUE;
    737     }
    738     LOGD("E camera id %d", hw->getCameraId());
    739     hw->lockAPI();
    740     qcamera_api_result_t apiResult;
    741     ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
    742     if (ret == NO_ERROR) {
    743         hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
    744         ret = apiResult.enabled;
    745     }
    746     hw->unlockAPI();
    747     LOGD("X camera id %d", hw->getCameraId());
    748 
    749     return ret;
    750 }
    751 
    752 /*===========================================================================
    753  * FUNCTION   : release_recording_frame
    754  *
    755  * DESCRIPTION: return recording frame back
    756  *
    757  * PARAMETERS :
    758  *   @device  : ptr to camera device struct
    759  *   @opaque  : ptr to frame to be returned
    760  *
    761  * RETURN     : none
    762  *==========================================================================*/
    763 void QCamera2HardwareInterface::release_recording_frame(
    764             struct camera_device *device, const void *opaque)
    765 {
    766     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REL_REC_FRAME);
    767     int32_t ret = NO_ERROR;
    768     QCamera2HardwareInterface *hw =
    769         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    770     if (!hw) {
    771         LOGE("NULL camera device");
    772         return;
    773     }
    774     if (!opaque) {
    775         LOGE("Error!! Frame info is NULL");
    776         return;
    777     }
    778     LOGD("E camera id %d", hw->getCameraId());
    779 
    780     hw->lockAPI();
    781     qcamera_api_result_t apiResult;
    782     ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
    783     if (ret == NO_ERROR) {
    784         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
    785     }
    786     hw->unlockAPI();
    787     LOGD("X camera id %d", hw->getCameraId());
    788 }
    789 
    790 /*===========================================================================
    791  * FUNCTION   : auto_focus
    792  *
    793  * DESCRIPTION: start auto focus
    794  *
    795  * PARAMETERS :
    796  *   @device  : ptr to camera device struct
    797  *
    798  * RETURN     : int32_t type of status
    799  *              NO_ERROR  -- success
    800  *              none-zero failure code
    801  *==========================================================================*/
    802 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
    803 {
    804     KPI_ATRACE_INT("Camera:AutoFocus", 1);
    805     int ret = NO_ERROR;
    806     QCamera2HardwareInterface *hw =
    807         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    808     if (!hw) {
    809         LOGE("NULL camera device");
    810         return BAD_VALUE;
    811     }
    812     LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
    813              hw->getCameraId());
    814     hw->lockAPI();
    815     qcamera_api_result_t apiResult;
    816     ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
    817     if (ret == NO_ERROR) {
    818         hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
    819         ret = apiResult.status;
    820     }
    821     hw->unlockAPI();
    822     LOGH("[KPI Perf] : X ret = %d", ret);
    823 
    824     return ret;
    825 }
    826 
    827 /*===========================================================================
    828  * FUNCTION   : cancel_auto_focus
    829  *
    830  * DESCRIPTION: cancel auto focus
    831  *
    832  * PARAMETERS :
    833  *   @device  : ptr to camera device struct
    834  *
    835  * RETURN     : int32_t type of status
    836  *              NO_ERROR  -- success
    837  *              none-zero failure code
    838  *==========================================================================*/
    839 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
    840 {
    841     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_AF);
    842     int ret = NO_ERROR;
    843     QCamera2HardwareInterface *hw =
    844         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    845     if (!hw) {
    846         LOGE("NULL camera device");
    847         return BAD_VALUE;
    848     }
    849     LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
    850              hw->getCameraId());
    851     hw->lockAPI();
    852     qcamera_api_result_t apiResult;
    853     ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
    854     if (ret == NO_ERROR) {
    855         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
    856         ret = apiResult.status;
    857     }
    858     hw->unlockAPI();
    859     LOGH("[KPI Perf] : X ret = %d", ret);
    860     return ret;
    861 }
    862 
    863 /*===========================================================================
    864  * FUNCTION   : pre_take_picture
    865  *
    866  * DESCRIPTION: pre take picture, restart preview if necessary.
    867  *
    868  * PARAMETERS :
    869  *   @device  : ptr to camera device struct
    870  *
    871  * RETURN     : int32_t type of status
    872  *              NO_ERROR  -- success
    873  *              none-zero failure code
    874  *==========================================================================*/
    875 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
    876 {
    877     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_TAKE_PICTURE);
    878     int ret = NO_ERROR;
    879     QCamera2HardwareInterface *hw =
    880         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    881     if (!hw) {
    882         LOGE("NULL camera device");
    883         return BAD_VALUE;
    884     }
    885     LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
    886           hw->getCameraId());
    887     hw->lockAPI();
    888     qcamera_api_result_t apiResult;
    889     ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
    890     if (ret == NO_ERROR) {
    891         hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
    892         ret = apiResult.status;
    893     }
    894     hw->unlockAPI();
    895     LOGH("[KPI Perf]: X");
    896     return ret;
    897 }
    898 
    899 /*===========================================================================
    900  * FUNCTION   : take_picture
    901  *
    902  * DESCRIPTION: take picture
    903  *
    904  * PARAMETERS :
    905  *   @device  : ptr to camera device struct
    906  *
    907  * RETURN     : int32_t type of status
    908  *              NO_ERROR  -- success
    909  *              none-zero failure code
    910  *==========================================================================*/
    911 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
    912 {
    913     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_TAKE_PICTURE);
    914     int ret = NO_ERROR;
    915     QCamera2HardwareInterface *hw =
    916         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    917     if (!hw) {
    918         LOGE("NULL camera device");
    919         return BAD_VALUE;
    920     }
    921     LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
    922              hw->getCameraId());
    923 
    924     // Acquire the perf lock for JPEG snapshot only
    925     if (hw->mParameters.isJpegPictureFormat()) {
    926         hw->m_perfLockMgr.acquirePerfLock(PERF_LOCK_TAKE_SNAPSHOT);
    927     }
    928 
    929     qcamera_api_result_t apiResult;
    930 
    931    /** Added support for Retro-active Frames:
    932      *  takePicture() is called before preparing Snapshot to indicate the
    933      *  mm-camera-channel to pick up legacy frames even
    934      *  before LED estimation is triggered.
    935      */
    936 
    937     LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
    938            hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
    939            hw->isLongshotEnabled());
    940 
    941     // Check for Retro-active Frames
    942     if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
    943         !hw->isLiveSnapshot() && hw->isZSLMode() &&
    944         !hw->isHDRMode() && !hw->isLongshotEnabled()) {
    945         // Set Retro Picture Mode
    946         hw->setRetroPicture(1);
    947         hw->m_bLedAfAecLock = 0;
    948         LOGL("Retro Enabled");
    949 
    950         // Give HWI control to call pre_take_picture in single camera mode.
    951         // In dual-cam mode, this control belongs to muxer.
    952         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    953             ret = pre_take_picture(device);
    954             if (ret != NO_ERROR) {
    955                 LOGE("pre_take_picture failed with ret = %d",ret);
    956                 return ret;
    957             }
    958         }
    959 
    960         /* Call take Picture for total number of snapshots required.
    961              This includes the number of retro frames and normal frames */
    962         hw->lockAPI();
    963         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
    964         if (ret == NO_ERROR) {
    965           // Wait for retro frames, before calling prepare snapshot
    966           LOGD("Wait for Retro frames to be done");
    967           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
    968             ret = apiResult.status;
    969         }
    970         /* Unlock API since it is acquired in prepare snapshot seperately */
    971         hw->unlockAPI();
    972 
    973         /* Prepare snapshot in case LED needs to be flashed */
    974         LOGD("Start Prepare Snapshot");
    975         ret = hw->prepare_snapshot(device);
    976     }
    977     else {
    978         hw->setRetroPicture(0);
    979         // Check if prepare snapshot is done
    980         if (!hw->mPrepSnapRun) {
    981             // Ignore the status from prepare_snapshot
    982             hw->prepare_snapshot(device);
    983         }
    984 
    985         // Give HWI control to call pre_take_picture in single camera mode.
    986         // In dual-cam mode, this control belongs to muxer.
    987         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    988             ret = pre_take_picture(device);
    989             if (ret != NO_ERROR) {
    990                 LOGE("pre_take_picture failed with ret = %d",ret);
    991                 return ret;
    992             }
    993         }
    994 
    995         // Regardless what the result value for prepare_snapshot,
    996         // go ahead with capture anyway. Just like the way autofocus
    997         // is handled in capture case
    998         /* capture */
    999         LOGL("Capturing normal frames");
   1000         hw->lockAPI();
   1001         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
   1002         if (ret == NO_ERROR) {
   1003           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
   1004             ret = apiResult.status;
   1005         }
   1006         hw->unlockAPI();
   1007         if (!hw->isLongshotEnabled()){
   1008             // For longshot mode, we prepare snapshot only once
   1009             hw->mPrepSnapRun = false;
   1010          }
   1011     }
   1012     LOGI("[KPI Perf]: X ret = %d", ret);
   1013     return ret;
   1014 }
   1015 
   1016 /*===========================================================================
   1017  * FUNCTION   : cancel_picture
   1018  *
   1019  * DESCRIPTION: cancel current take picture request
   1020  *
   1021  * PARAMETERS :
   1022  *   @device  : ptr to camera device struct
   1023  *
   1024  * RETURN     : int32_t type of status
   1025  *              NO_ERROR  -- success
   1026  *              none-zero failure code
   1027  *==========================================================================*/
   1028 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
   1029 {
   1030     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_PICTURE);
   1031     int ret = NO_ERROR;
   1032     QCamera2HardwareInterface *hw =
   1033         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1034     if (!hw) {
   1035         LOGE("NULL camera device");
   1036         return BAD_VALUE;
   1037     }
   1038     LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
   1039              hw->getCameraId());
   1040     hw->lockAPI();
   1041     qcamera_api_result_t apiResult;
   1042     ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
   1043     if (ret == NO_ERROR) {
   1044         hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
   1045         ret = apiResult.status;
   1046     }
   1047     hw->unlockAPI();
   1048     LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);
   1049 
   1050     return ret;
   1051 }
   1052 
   1053 /*===========================================================================
   1054  * FUNCTION   : set_parameters
   1055  *
   1056  * DESCRIPTION: set camera parameters
   1057  *
   1058  * PARAMETERS :
   1059  *   @device  : ptr to camera device struct
   1060  *   @parms   : string of packed parameters
   1061  *
   1062  * RETURN     : int32_t type of status
   1063  *              NO_ERROR  -- success
   1064  *              none-zero failure code
   1065  *==========================================================================*/
   1066 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
   1067                                               const char *parms)
   1068 {
   1069     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PARAMETERS);
   1070     int ret = NO_ERROR;
   1071     QCamera2HardwareInterface *hw =
   1072         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1073     if (!hw) {
   1074         LOGE("NULL camera device");
   1075         return BAD_VALUE;
   1076     }
   1077     LOGD("E camera id %d", hw->getCameraId());
   1078     hw->lockAPI();
   1079     qcamera_api_result_t apiResult;
   1080     ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
   1081     if (ret == NO_ERROR) {
   1082         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
   1083         ret = apiResult.status;
   1084     }
   1085 
   1086     // Give HWI control to restart (if necessary) after set params
   1087     // in single camera mode. In dual-cam mode, this control belongs to muxer.
   1088     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   1089         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
   1090             LOGD("stopping after param change");
   1091             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
   1092             if (ret == NO_ERROR) {
   1093                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
   1094                 ret = apiResult.status;
   1095             }
   1096         }
   1097 
   1098         if (ret == NO_ERROR) {
   1099             LOGD("committing param change");
   1100             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
   1101             if (ret == NO_ERROR) {
   1102                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
   1103                 ret = apiResult.status;
   1104             }
   1105         }
   1106 
   1107         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
   1108             LOGD("restarting after param change");
   1109             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
   1110             if (ret == NO_ERROR) {
   1111                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
   1112                 ret = apiResult.status;
   1113             }
   1114         }
   1115     }
   1116 
   1117     hw->unlockAPI();
   1118     LOGD("X camera id %d ret %d", hw->getCameraId(), ret);
   1119 
   1120     return ret;
   1121 }
   1122 
   1123 /*===========================================================================
   1124  * FUNCTION   : stop_after_set_params
   1125  *
   1126  * DESCRIPTION: stop after a set param call, if necessary
   1127  *
   1128  * PARAMETERS :
   1129  *   @device  : ptr to camera device struct
   1130  *
   1131  * RETURN     : int32_t type of status
   1132  *              NO_ERROR  -- success
   1133  *              none-zero failure code
   1134  *==========================================================================*/
   1135 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
   1136 {
   1137     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_AFTER_SET_PARAMS);
   1138     int ret = NO_ERROR;
   1139     QCamera2HardwareInterface *hw =
   1140         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1141     if (!hw) {
   1142         LOGE("NULL camera device");
   1143         return BAD_VALUE;
   1144     }
   1145     LOGD("E camera id %d", hw->getCameraId());
   1146     hw->lockAPI();
   1147     qcamera_api_result_t apiResult;
   1148 
   1149     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1150         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
   1151         if (ret == NO_ERROR) {
   1152             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
   1153             ret = apiResult.status;
   1154         }
   1155     } else {
   1156         LOGE("is not supposed to be called in single-camera mode");
   1157         ret = INVALID_OPERATION;
   1158     }
   1159 
   1160     hw->unlockAPI();
   1161     LOGD("X camera id %d", hw->getCameraId());
   1162 
   1163     return ret;
   1164 }
   1165 
   1166 /*===========================================================================
   1167  * FUNCTION   : commit_params
   1168  *
   1169  * DESCRIPTION: commit after a set param call
   1170  *
   1171  * PARAMETERS :
   1172  *   @device  : ptr to camera device struct
   1173  *
   1174  * RETURN     : int32_t type of status
   1175  *              NO_ERROR  -- success
   1176  *              none-zero failure code
   1177  *==========================================================================*/
   1178 int QCamera2HardwareInterface::commit_params(struct camera_device *device)
   1179 {
   1180     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_COMMIT_PARAMS);
   1181     int ret = NO_ERROR;
   1182     QCamera2HardwareInterface *hw =
   1183         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1184     if (!hw) {
   1185         LOGE("NULL camera device");
   1186         return BAD_VALUE;
   1187     }
   1188     LOGD("E camera id %d", hw->getCameraId());
   1189     hw->lockAPI();
   1190     qcamera_api_result_t apiResult;
   1191 
   1192     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1193         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
   1194         if (ret == NO_ERROR) {
   1195             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
   1196             ret = apiResult.status;
   1197         }
   1198     } else {
   1199         LOGE("is not supposed to be called in single-camera mode");
   1200         ret = INVALID_OPERATION;
   1201     }
   1202 
   1203     hw->unlockAPI();
   1204     LOGD("X camera id %d", hw->getCameraId());
   1205 
   1206     return ret;
   1207 }
   1208 
   1209 /*===========================================================================
   1210  * FUNCTION   : restart_after_set_params
   1211  *
   1212  * DESCRIPTION: restart after a set param call, if necessary
   1213  *
   1214  * PARAMETERS :
   1215  *   @device  : ptr to camera device struct
   1216  *
   1217  * RETURN     : int32_t type of status
   1218  *              NO_ERROR  -- success
   1219  *              none-zero failure code
   1220  *==========================================================================*/
   1221 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
   1222 {
   1223     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_AFTER_SET_PARAMS);
   1224     int ret = NO_ERROR;
   1225     QCamera2HardwareInterface *hw =
   1226         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1227     if (!hw) {
   1228         LOGE("NULL camera device");
   1229         return BAD_VALUE;
   1230     }
   1231     LOGD("E camera id %d", hw->getCameraId());
   1232     hw->lockAPI();
   1233     qcamera_api_result_t apiResult;
   1234 
   1235     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1236         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
   1237         if (ret == NO_ERROR) {
   1238             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
   1239             ret = apiResult.status;
   1240         }
   1241     } else {
   1242         LOGE("is not supposed to be called in single-camera mode");
   1243         ret = INVALID_OPERATION;
   1244     }
   1245 
   1246     hw->unlockAPI();
   1247     LOGD("X camera id %d", hw->getCameraId());
   1248     return ret;
   1249 }
   1250 
   1251 /*===========================================================================
   1252  * FUNCTION   : get_parameters
   1253  *
   1254  * DESCRIPTION: query camera parameters
   1255  *
   1256  * PARAMETERS :
   1257  *   @device  : ptr to camera device struct
   1258  *
   1259  * RETURN     : packed parameters in a string
   1260  *==========================================================================*/
   1261 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
   1262 {
   1263     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_PARAMETERS);
   1264     char *ret = NULL;
   1265     QCamera2HardwareInterface *hw =
   1266         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1267     if (!hw) {
   1268         LOGE("NULL camera device");
   1269         return NULL;
   1270     }
   1271     LOGD("E camera id %d", hw->getCameraId());
   1272     hw->lockAPI();
   1273     qcamera_api_result_t apiResult;
   1274     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
   1275     if (rc == NO_ERROR) {
   1276         hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
   1277         ret = apiResult.params;
   1278     }
   1279     hw->unlockAPI();
   1280     LOGD("E camera id %d", hw->getCameraId());
   1281 
   1282     return ret;
   1283 }
   1284 
   1285 /*===========================================================================
   1286  * FUNCTION   : put_parameters
   1287  *
   1288  * DESCRIPTION: return camera parameters string back to HAL
   1289  *
   1290  * PARAMETERS :
   1291  *   @device  : ptr to camera device struct
   1292  *   @parm    : ptr to parameter string to be returned
   1293  *
   1294  * RETURN     : none
   1295  *==========================================================================*/
   1296 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
   1297                                                char *parm)
   1298 {
   1299     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PUT_PARAMETERS);
   1300     QCamera2HardwareInterface *hw =
   1301         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1302     if (!hw) {
   1303         LOGE("NULL camera device");
   1304         return;
   1305     }
   1306     LOGD("E camera id %d", hw->getCameraId());
   1307     hw->lockAPI();
   1308     qcamera_api_result_t apiResult;
   1309     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
   1310     if (ret == NO_ERROR) {
   1311         hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
   1312     }
   1313     hw->unlockAPI();
   1314     LOGD("E camera id %d", hw->getCameraId());
   1315 }
   1316 
   1317 /*===========================================================================
   1318  * FUNCTION   : send_command
   1319  *
   1320  * DESCRIPTION: command to be executed
   1321  *
   1322  * PARAMETERS :
   1323  *   @device  : ptr to camera device struct
   1324  *   @cmd     : cmd to be executed
   1325  *   @arg1    : ptr to optional argument1
   1326  *   @arg2    : ptr to optional argument2
   1327  *
   1328  * RETURN     : int32_t type of status
   1329  *              NO_ERROR  -- success
   1330  *              none-zero failure code
   1331  *==========================================================================*/
   1332 int QCamera2HardwareInterface::send_command(struct camera_device *device,
   1333                                             int32_t cmd,
   1334                                             int32_t arg1,
   1335                                             int32_t arg2)
   1336 {
   1337     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND);
   1338     int ret = NO_ERROR;
   1339     QCamera2HardwareInterface *hw =
   1340         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1341     if (!hw) {
   1342         LOGE("NULL camera device");
   1343         return BAD_VALUE;
   1344     }
   1345     LOGD("E camera id %d", hw->getCameraId());
   1346 
   1347     qcamera_sm_evt_command_payload_t payload;
   1348     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
   1349     payload.cmd = cmd;
   1350     payload.arg1 = arg1;
   1351     payload.arg2 = arg2;
   1352     hw->lockAPI();
   1353     qcamera_api_result_t apiResult;
   1354     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
   1355     if (ret == NO_ERROR) {
   1356         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
   1357         ret = apiResult.status;
   1358     }
   1359     hw->unlockAPI();
   1360     LOGD("E camera id %d", hw->getCameraId());
   1361 
   1362     return ret;
   1363 }
   1364 
   1365 /*===========================================================================
   1366  * FUNCTION   : send_command_restart
   1367  *
   1368  * DESCRIPTION: restart if necessary after a send_command
   1369  *
   1370  * PARAMETERS :
   1371  *   @device  : ptr to camera device struct
   1372  *   @cmd     : cmd to be executed
   1373  *   @arg1    : ptr to optional argument1
   1374  *   @arg2    : ptr to optional argument2
   1375  *
   1376  * RETURN     : int32_t type of status
   1377  *              NO_ERROR  -- success
   1378  *              none-zero failure code
   1379  *==========================================================================*/
   1380 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
   1381         int32_t cmd,
   1382         int32_t arg1,
   1383         int32_t arg2)
   1384 {
   1385     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND_RESTART);
   1386     int ret = NO_ERROR;
   1387     QCamera2HardwareInterface *hw =
   1388             reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1389     if (!hw) {
   1390         LOGE("NULL camera device");
   1391         return BAD_VALUE;
   1392     }
   1393 
   1394     qcamera_sm_evt_command_payload_t payload;
   1395     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
   1396     payload.cmd = cmd;
   1397     payload.arg1 = arg1;
   1398     payload.arg2 = arg2;
   1399     hw->lockAPI();
   1400     qcamera_api_result_t apiResult;
   1401     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
   1402     if (ret == NO_ERROR) {
   1403         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
   1404         ret = apiResult.status;
   1405     }
   1406     hw->unlockAPI();
   1407     LOGD("E camera id %d", hw->getCameraId());
   1408 
   1409     return ret;
   1410 }
   1411 
   1412 /*===========================================================================
   1413  * FUNCTION   : release
   1414  *
   1415  * DESCRIPTION: release camera resource
   1416  *
   1417  * PARAMETERS :
   1418  *   @device  : ptr to camera device struct
   1419  *
   1420  * RETURN     : none
   1421  *==========================================================================*/
   1422 void QCamera2HardwareInterface::release(struct camera_device *device)
   1423 {
   1424     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RELEASE);
   1425     QCamera2HardwareInterface *hw =
   1426         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1427     if (!hw) {
   1428         LOGE("NULL camera device");
   1429         return;
   1430     }
   1431     LOGD("E camera id %d", hw->getCameraId());
   1432     hw->lockAPI();
   1433     qcamera_api_result_t apiResult;
   1434     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
   1435     if (ret == NO_ERROR) {
   1436         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
   1437     }
   1438     hw->unlockAPI();
   1439     LOGD("E camera id %d", hw->getCameraId());
   1440 }
   1441 
   1442 /*===========================================================================
   1443  * FUNCTION   : dump
   1444  *
   1445  * DESCRIPTION: dump camera status
   1446  *
   1447  * PARAMETERS :
   1448  *   @device  : ptr to camera device struct
   1449  *   @fd      : fd for status to be dumped to
   1450  *
   1451  * RETURN     : int32_t type of status
   1452  *              NO_ERROR  -- success
   1453  *              none-zero failure code
   1454  *==========================================================================*/
   1455 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
   1456 {
   1457     int ret = NO_ERROR;
   1458 
   1459     //Log level property is read when "adb shell dumpsys media.camera" is
   1460     //called so that the log level can be controlled without restarting
   1461     //media server
   1462     getLogLevel();
   1463     QCamera2HardwareInterface *hw =
   1464         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1465     if (!hw) {
   1466         LOGE("NULL camera device");
   1467         return BAD_VALUE;
   1468     }
   1469     LOGD("E camera id %d", hw->getCameraId());
   1470     hw->lockAPI();
   1471     qcamera_api_result_t apiResult;
   1472     ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
   1473     if (ret == NO_ERROR) {
   1474         hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
   1475         ret = apiResult.status;
   1476     }
   1477     hw->unlockAPI();
   1478     LOGD("E camera id %d", hw->getCameraId());
   1479 
   1480     return ret;
   1481 }
   1482 
   1483 /*===========================================================================
   1484  * FUNCTION   : close_camera_device
   1485  *
   1486  * DESCRIPTION: close camera device
   1487  *
   1488  * PARAMETERS :
   1489  *   @device  : ptr to camera device struct
   1490  *
   1491  * RETURN     : int32_t type of status
   1492  *              NO_ERROR  -- success
   1493  *              none-zero failure code
   1494  *==========================================================================*/
   1495 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
   1496 {
   1497     KPI_ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_HAL1_CLOSECAMERA);
   1498     int ret = NO_ERROR;
   1499 
   1500     QCamera2HardwareInterface *hw =
   1501         reinterpret_cast<QCamera2HardwareInterface *>(
   1502             reinterpret_cast<camera_device_t *>(hw_dev)->priv);
   1503     if (!hw) {
   1504         LOGE("NULL camera device");
   1505         return BAD_VALUE;
   1506     }
   1507     LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
   1508     delete hw;
   1509     LOGI("[KPI Perf]: X");
   1510     KPI_ATRACE_CAMSCOPE_END(CAMSCOPE_HAL1_CLOSECAMERA);
   1511     CAMSCOPE_DESTROY(CAMSCOPE_SECTION_HAL);
   1512     return ret;
   1513 }
   1514 
   1515 /*===========================================================================
   1516  * FUNCTION   : register_face_image
   1517  *
   1518  * DESCRIPTION: register a face image into imaging lib for face authenticatio/
   1519  *              face recognition
   1520  *
   1521  * PARAMETERS :
   1522  *   @device  : ptr to camera device struct
   1523  *   @img_ptr : ptr to image buffer
   1524  *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
   1525  *
   1526  * RETURN     : >=0 unique ID of face registerd.
   1527  *              <0  failure.
   1528  *==========================================================================*/
   1529 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
   1530                                                    void *img_ptr,
   1531                                                    cam_pp_offline_src_config_t *config)
   1532 {
   1533     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REGISTER_FACE_IMAGE);
   1534     int ret = NO_ERROR;
   1535     QCamera2HardwareInterface *hw =
   1536         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1537     if (!hw) {
   1538         LOGE("NULL camera device");
   1539         return BAD_VALUE;
   1540     }
   1541     LOGD("E camera id %d", hw->getCameraId());
   1542     qcamera_sm_evt_reg_face_payload_t payload;
   1543     memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
   1544     payload.img_ptr = img_ptr;
   1545     payload.config = config;
   1546     hw->lockAPI();
   1547     qcamera_api_result_t apiResult;
   1548     ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
   1549     if (ret == NO_ERROR) {
   1550         hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
   1551         ret = apiResult.handle;
   1552     }
   1553     hw->unlockAPI();
   1554     LOGD("E camera id %d", hw->getCameraId());
   1555 
   1556     return ret;
   1557 }
   1558 
   1559 /*===========================================================================
   1560  * FUNCTION   : prepare_snapshot
   1561  *
   1562  * DESCRIPTION: prepares hardware for snapshot
   1563  *
   1564  * PARAMETERS :
   1565  *   @device  : ptr to camera device struct
   1566  *
   1567  * RETURN     : int32_t type of status
   1568  *              NO_ERROR  -- success
   1569  *              none-zero failure code
   1570  *==========================================================================*/
   1571 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
   1572 {
   1573     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_SNAPSHOT);
   1574     int ret = NO_ERROR;
   1575     QCamera2HardwareInterface *hw =
   1576         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1577     if (!hw) {
   1578         LOGE("NULL camera device");
   1579         return BAD_VALUE;
   1580     }
   1581     if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
   1582         // For longshot mode, we prepare snapshot only once
   1583         LOGH("prepare snapshot only once ");
   1584         return NO_ERROR;
   1585     }
   1586     LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
   1587              hw->getCameraId());
   1588     hw->lockAPI();
   1589     qcamera_api_result_t apiResult;
   1590 
   1591     /* Prepare snapshot in case LED needs to be flashed */
   1592     if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
   1593         /* Prepare snapshot in case LED needs to be flashed */
   1594         ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
   1595         if (ret == NO_ERROR) {
   1596           hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
   1597             ret = apiResult.status;
   1598         }
   1599         hw->mPrepSnapRun = true;
   1600     }
   1601     hw->unlockAPI();
   1602     LOGH("[KPI Perf]: X, ret: %d", ret);
   1603     return ret;
   1604 }
   1605 
   1606 /*===========================================================================
   1607  * FUNCTION   : QCamera2HardwareInterface
   1608  *
   1609  * DESCRIPTION: constructor of QCamera2HardwareInterface
   1610  *
   1611  * PARAMETERS :
   1612  *   @cameraId  : camera ID
   1613  *
   1614  * RETURN     : none
   1615  *==========================================================================*/
   1616 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
   1617     : mCameraId(cameraId),
   1618       mCameraHandle(NULL),
   1619       mMasterCamera(CAM_TYPE_MAIN),
   1620       mCameraOpened(false),
   1621       mDualCamera(false),
   1622       m_pFovControl(NULL),
   1623       m_bRelCamCalibValid(false),
   1624       mPreviewWindow(NULL),
   1625       mMsgEnabled(0),
   1626       mStoreMetaDataInFrame(0),
   1627       mJpegCb(NULL),
   1628       mCallbackCookie(NULL),
   1629       mJpegCallbackCookie(NULL),
   1630       m_bMpoEnabled(TRUE),
   1631       m_stateMachine(this),
   1632       m_smThreadActive(true),
   1633       m_postprocessor(this),
   1634       m_thermalAdapter(QCameraThermalAdapter::getInstance()),
   1635       m_cbNotifier(this),
   1636       m_perfLockMgr(),
   1637       m_bPreviewStarted(false),
   1638       m_bRecordStarted(false),
   1639       m_currentFocusState(CAM_AF_STATE_INACTIVE),
   1640       mDumpFrmCnt(0U),
   1641       mDumpSkipCnt(0U),
   1642       mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
   1643       mActiveAF(false),
   1644       m_HDRSceneEnabled(false),
   1645       mLongshotEnabled(false),
   1646       mLiveSnapshotThread(0),
   1647       mIntPicThread(0),
   1648       mFlashNeeded(false),
   1649       mFlashConfigured(false),
   1650       mDeviceRotation(0U),
   1651       mCaptureRotation(0U),
   1652       mJpegExifRotation(0U),
   1653       mUseJpegExifRotation(false),
   1654       mIs3ALocked(false),
   1655       mPrepSnapRun(false),
   1656       mZoomLevel(0),
   1657       mPreviewRestartNeeded(false),
   1658       mVFrameCount(0),
   1659       mVLastFrameCount(0),
   1660       mVLastFpsTime(0),
   1661       mVFps(0),
   1662       mPFrameCount(0),
   1663       mPLastFrameCount(0),
   1664       mPLastFpsTime(0),
   1665       mPFps(0),
   1666       mLowLightConfigured(false),
   1667       mInstantAecFrameCount(0),
   1668       m_bIntJpegEvtPending(false),
   1669       m_bIntRawEvtPending(false),
   1670       mReprocJob(0),
   1671       mJpegJob(0),
   1672       mMetadataAllocJob(0),
   1673       mInitPProcJob(0),
   1674       mParamAllocJob(0),
   1675       mParamInitJob(0),
   1676       mOutputCount(0),
   1677       mInputCount(0),
   1678       mAdvancedCaptureConfigured(false),
   1679       mHDRBracketingEnabled(false),
   1680       mNumPreviewFaces(-1),
   1681       mJpegClientHandle(0),
   1682       mJpegHandleOwner(false),
   1683       mMetadataMem(NULL),
   1684       mCACDoneReceived(false),
   1685       m_bNeedRestart(false),
   1686       mBootToMonoTimestampOffset(0),
   1687       bDepthAFCallbacks(true),
   1688       m_bNeedHalPP(FALSE)
   1689 {
   1690 #ifdef TARGET_TS_MAKEUP
   1691     memset(&mFaceRect, -1, sizeof(mFaceRect));
   1692 #endif
   1693     getLogLevel();
   1694     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_QCAMERA2HWI);
   1695     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
   1696     mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
   1697     mCameraDevice.common.close = close_camera_device;
   1698     mCameraDevice.ops = &mCameraOps;
   1699     mCameraDevice.priv = this;
   1700 
   1701     mDualCamera = is_dual_camera_by_idx(cameraId);
   1702 
   1703     pthread_mutex_init(&m_lock, NULL);
   1704     pthread_cond_init(&m_cond, NULL);
   1705 
   1706     m_apiResultList = NULL;
   1707 
   1708     pthread_mutex_init(&m_evtLock, NULL);
   1709     pthread_cond_init(&m_evtCond, NULL);
   1710     memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
   1711 
   1712 
   1713     pthread_mutex_init(&m_int_lock, NULL);
   1714     pthread_cond_init(&m_int_cond, NULL);
   1715 
   1716     memset(m_channels, 0, sizeof(m_channels));
   1717 
   1718     memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
   1719 
   1720     memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
   1721 
   1722     memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
   1723     memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
   1724     memset(&mJpegHandle, 0, sizeof(mJpegHandle));
   1725     memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
   1726 
   1727     mDeferredWorkThread.launch(deferredWorkRoutine, this);
   1728     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
   1729 
   1730     pthread_mutex_init(&mGrallocLock, NULL);
   1731     mEnqueuedBuffers = 0;
   1732     mFrameSkipStart = 0;
   1733     mFrameSkipEnd = 0;
   1734     mLastPreviewFrameID = 0;
   1735 
   1736     //Load and read GPU library.
   1737     lib_surface_utils = NULL;
   1738     LINK_get_surface_pixel_alignment = NULL;
   1739     mSurfaceStridePadding = CAM_PAD_TO_32;
   1740     lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
   1741     if (lib_surface_utils) {
   1742         *(void **)&LINK_get_surface_pixel_alignment =
   1743                 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
   1744          if (LINK_get_surface_pixel_alignment) {
   1745              mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
   1746          }
   1747          dlclose(lib_surface_utils);
   1748     }
   1749 }
   1750 
   1751 /*===========================================================================
   1752  * FUNCTION   : ~QCamera2HardwareInterface
   1753  *
   1754  * DESCRIPTION: destructor of QCamera2HardwareInterface
   1755  *
   1756  * PARAMETERS : none
   1757  *
   1758  * RETURN     : none
   1759  *==========================================================================*/
   1760 QCamera2HardwareInterface::~QCamera2HardwareInterface()
   1761 {
   1762     LOGH("E");
   1763 
   1764     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
   1765     mDeferredWorkThread.exit();
   1766 
   1767     if (mMetadataMem != NULL) {
   1768         delete mMetadataMem;
   1769         mMetadataMem = NULL;
   1770     }
   1771 
   1772     if (m_pFovControl) {
   1773         delete m_pFovControl;
   1774         m_pFovControl = NULL;
   1775     }
   1776 
   1777     m_perfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA);
   1778     lockAPI();
   1779     m_smThreadActive = false;
   1780     unlockAPI();
   1781     m_stateMachine.releaseThread();
   1782     closeCamera();
   1783     m_perfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA);
   1784 
   1785     pthread_mutex_destroy(&m_lock);
   1786     pthread_cond_destroy(&m_cond);
   1787     pthread_mutex_destroy(&m_evtLock);
   1788     pthread_cond_destroy(&m_evtCond);
   1789     pthread_mutex_destroy(&m_int_lock);
   1790     pthread_cond_destroy(&m_int_cond);
   1791     pthread_mutex_destroy(&mGrallocLock);
   1792     LOGH("X");
   1793 }
   1794 
   1795 /*===========================================================================
   1796  * FUNCTION   : deferPPInit
   1797  *
   1798  * DESCRIPTION: Queue postproc init task to deferred thread
   1799  *
   1800  * PARAMETERS : none
   1801  *
   1802  * RETURN     : uint32_t job id of pproc init job
   1803  *              0  -- failure
   1804  *==========================================================================*/
   1805 uint32_t QCamera2HardwareInterface::deferPPInit()
   1806 {
   1807     // init pproc
   1808     DeferWorkArgs args;
   1809     DeferPProcInitArgs pprocInitArgs;
   1810 
   1811     memset(&args, 0, sizeof(DeferWorkArgs));
   1812     memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
   1813 
   1814     pprocInitArgs.jpeg_cb = jpegEvtHandle;
   1815     pprocInitArgs.user_data = this;
   1816     args.pprocInitArgs = pprocInitArgs;
   1817 
   1818     return queueDeferredWork(CMD_DEF_PPROC_INIT,
   1819             args);
   1820 }
   1821 
   1822 /*===========================================================================
   1823  * FUNCTION   : openCamera
   1824  *
   1825  * DESCRIPTION: open camera
   1826  *
   1827  * PARAMETERS :
   1828  *   @hw_device  : double ptr for camera device struct
   1829  *
   1830  * RETURN     : int32_t type of status
   1831  *              NO_ERROR  -- success
   1832  *              none-zero failure code
   1833  *==========================================================================*/
   1834 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
   1835 {
   1836     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_OPENCAMERA);
   1837     int rc = NO_ERROR;
   1838     if (mCameraOpened) {
   1839         *hw_device = NULL;
   1840         LOGE("Permission Denied");
   1841         return PERMISSION_DENIED;
   1842     }
   1843     LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
   1844             mCameraId);
   1845 
   1846     m_perfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);
   1847 
   1848     rc = openCamera();
   1849     if (rc == NO_ERROR){
   1850         *hw_device = &mCameraDevice.common;
   1851         if (m_thermalAdapter.init(this) != 0) {
   1852           LOGW("Init thermal adapter failed");
   1853         }
   1854     }
   1855     else
   1856         *hw_device = NULL;
   1857 
   1858     LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
   1859             mCameraId, rc);
   1860 
   1861     return rc;
   1862 }
   1863 
   1864 /*===========================================================================
   1865  * FUNCTION   : openCamera
   1866  *
   1867  * DESCRIPTION: open camera
   1868  *
   1869  * PARAMETERS : none
   1870  *
   1871  * RETURN     : int32_t type of status
   1872  *              NO_ERROR  -- success
   1873  *              none-zero failure code
   1874  *==========================================================================*/
   1875 int QCamera2HardwareInterface::openCamera()
   1876 {
   1877     int32_t rc = NO_ERROR;
   1878     char value[PROPERTY_VALUE_MAX];
   1879 
   1880     if (mCameraHandle) {
   1881         LOGE("Failure: Camera already opened");
   1882         return ALREADY_EXISTS;
   1883     }
   1884 
   1885     rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
   1886     if (rc < 0) {
   1887         LOGE("Failed to reserve flash for camera id: %d",
   1888                 mCameraId);
   1889         return UNKNOWN_ERROR;
   1890     }
   1891 
   1892     // alloc param buffer
   1893     DeferWorkArgs args;
   1894     memset(&args, 0, sizeof(args));
   1895     mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
   1896     if (mParamAllocJob == 0) {
   1897         LOGE("Failed queueing PARAM_ALLOC job");
   1898         return -ENOMEM;
   1899     }
   1900 
   1901     if (gCamCapability[mCameraId] != NULL) {
   1902         // allocate metadata buffers
   1903         DeferWorkArgs args;
   1904         DeferMetadataAllocArgs metadataAllocArgs;
   1905 
   1906         memset(&args, 0, sizeof(args));
   1907         memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
   1908 
   1909         uint32_t padding =
   1910                 gCamCapability[mCameraId]->padding_info.plane_padding;
   1911         metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
   1912                 padding);
   1913         metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
   1914         args.metadataAllocArgs = metadataAllocArgs;
   1915 
   1916         mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
   1917         if (mMetadataAllocJob == 0) {
   1918             LOGE("Failed to allocate metadata buffer");
   1919             rc = -ENOMEM;
   1920             goto error_exit1;
   1921         }
   1922 
   1923         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
   1924         if (rc) {
   1925             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
   1926                      rc, mCameraHandle);
   1927             goto error_exit2;
   1928         }
   1929 
   1930         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
   1931                 camEvtHandle,
   1932                 (void *) this);
   1933     } else {
   1934         LOGH("Capabilities not inited, initializing now.");
   1935 
   1936         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
   1937         if (rc) {
   1938             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
   1939                      rc, mCameraHandle);
   1940             goto error_exit2;
   1941         }
   1942 
   1943         if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
   1944             LOGE("initCapabilities failed.");
   1945             rc = UNKNOWN_ERROR;
   1946             goto error_exit3;
   1947         }
   1948 
   1949         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
   1950                 camEvtHandle,
   1951                 (void *) this);
   1952     }
   1953     mBundledSnapshot = 0;
   1954     mActiveCameras = MM_CAMERA_TYPE_MAIN;
   1955     if (isDualCamera()) {
   1956         mActiveCameras |= MM_CAMERA_TYPE_AUX;
   1957 
   1958         // Create and initialize FOV-control object
   1959         m_pFovControl = QCameraFOVControl::create(gCamCapability[mCameraId]->main_cam_cap,
   1960                 gCamCapability[mCameraId]->aux_cam_cap);
   1961         if (m_pFovControl) {
   1962             *gCamCapability[mCameraId] = m_pFovControl->consolidateCapabilities(
   1963                     gCamCapability[mCameraId]->main_cam_cap,
   1964                     gCamCapability[mCameraId]->aux_cam_cap);
   1965         } else {
   1966             LOGE("FOV-control: Failed to create an object");
   1967             rc = NO_MEMORY;
   1968             goto error_exit3;
   1969         }
   1970     }
   1971 
   1972     // Init params in the background
   1973     // 1. It's safe to queue init job, even if alloc job is not yet complete.
   1974     // It will be queued to the same thread, so the alloc is guaranteed to
   1975     // finish first.
   1976     // 2. However, it is not safe to begin param init until after camera is
   1977     // open. That is why we wait until after camera open completes to schedule
   1978     // this task.
   1979     memset(&args, 0, sizeof(args));
   1980     mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
   1981     if (mParamInitJob == 0) {
   1982         LOGE("Failed queuing PARAM_INIT job");
   1983         rc = -ENOMEM;
   1984         goto error_exit3;
   1985     }
   1986 
   1987     mCameraOpened = true;
   1988 
   1989     //Notify display HAL that a camera session is active.
   1990     //But avoid calling the same during bootup because camera service might open/close
   1991     //cameras at boot time during its initialization and display service will also internally
   1992     //wait for camera service to initialize first while calling this display API, resulting in a
   1993     //deadlock situation. Since boot time camera open/close calls are made only to fetch
   1994     //capabilities, no need of this display bw optimization.
   1995     //Use "service.bootanim.exit" property to know boot status.
   1996     property_get("service.bootanim.exit", value, "0");
   1997     if (atoi(value) == 1) {
   1998         pthread_mutex_lock(&gCamLock);
   1999         if (gNumCameraSessions++ == 0) {
   2000             setCameraLaunchStatus(true);
   2001         }
   2002         pthread_mutex_unlock(&gCamLock);
   2003     }
   2004 
   2005     // Setprop to decide the time source (whether boottime or monotonic).
   2006     // By default, use monotonic time.
   2007     property_get("persist.camera.time.monotonic", value, "1");
   2008     mBootToMonoTimestampOffset = 0;
   2009     if (atoi(value) == 1) {
   2010         // if monotonic is set, then need to use time in monotonic.
   2011         // So, Measure the clock offset between BOOTTIME and MONOTONIC
   2012         // The clock domain source for ISP is BOOTTIME and
   2013         // for Video/display is MONOTONIC
   2014         // The below offset is used to convert from clock domain of other subsystem
   2015         // (video/hardware composer) to that of camera. Assumption is that this
   2016         // offset won't change during the life cycle of the camera device. In other
   2017         // words, camera device shouldn't be open during CPU suspend.
   2018         mBootToMonoTimestampOffset = getBootToMonoTimeOffset();
   2019     }
   2020     LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset);
   2021 
   2022     memset(value, 0, sizeof(value));
   2023     property_get("persist.camera.depth.focus.cb", value, "1");
   2024     bDepthAFCallbacks = atoi(value);
   2025 
   2026     memset(value, 0, sizeof(value));
   2027     property_get("persist.camera.cache.optimize", value, "1");
   2028     m_bOptimizeCacheOps = atoi(value);
   2029 
   2030     return NO_ERROR;
   2031 
   2032 error_exit3:
   2033     if(mJpegClientHandle) {
   2034         deinitJpegHandle();
   2035     }
   2036     mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
   2037     mCameraHandle = NULL;
   2038 error_exit2:
   2039     waitDeferredWork(mMetadataAllocJob);
   2040 error_exit1:
   2041     waitDeferredWork(mParamAllocJob);
   2042     return rc;
   2043 
   2044 }
   2045 
   2046 /*===========================================================================
   2047  * FUNCTION   : bundleRelatedCameras
   2048  *
   2049  * DESCRIPTION: bundle cameras to enable syncing of cameras
   2050  *
   2051  * PARAMETERS :
   2052  *   @sync        :indicates whether syncing is On or Off
   2053  *
   2054  * RETURN     : int32_t type of status
   2055  *              NO_ERROR  -- success
   2056  *              none-zero failure code
   2057  *==========================================================================*/
   2058 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn)
   2059 {
   2060     int32_t rc = mParameters.bundleRelatedCameras(syncOn);
   2061     if (rc != NO_ERROR) {
   2062         LOGE("bundleRelatedCameras failed %d", rc);
   2063         return rc;
   2064     }
   2065     return rc;
   2066 }
   2067 
   2068 /*===========================================================================
   2069  * FUNCTION   : getCameraSessionId
   2070  *
   2071  * DESCRIPTION: gets the backend session Id of this HWI instance
   2072  *
   2073  * PARAMETERS :
   2074  *   @sessionid  : pointer to the output session id
   2075  *
   2076  * RETURN     : int32_t type of status
   2077  *              NO_ERROR  -- success
   2078  *              none-zero failure code
   2079  *==========================================================================*/
   2080 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
   2081 {
   2082     int32_t rc = NO_ERROR;
   2083 
   2084     if(session_id != NULL) {
   2085         rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
   2086                 session_id);
   2087         LOGD("Getting Camera Session Id %d", *session_id);
   2088     } else {
   2089         LOGE("Session Id is Null");
   2090         return UNKNOWN_ERROR;
   2091     }
   2092     return rc;
   2093 }
   2094 
   2095 /*===========================================================================
   2096  * FUNCTION   : isFrameSyncEnabled
   2097  *
   2098  * DESCRIPTION: returns whether frame sync is enabled
   2099  *
   2100  * PARAMETERS : none
   2101  *
   2102  * RETURN     : bool indicating whether frame sync is enabled
   2103  *==========================================================================*/
   2104 bool QCamera2HardwareInterface::isFrameSyncEnabled(void)
   2105 {
   2106     return mParameters.isFrameSyncEnabled();
   2107 }
   2108 
   2109 /*===========================================================================
   2110  * FUNCTION   : setFrameSyncEnabled
   2111  *
   2112  * DESCRIPTION: sets whether frame sync is enabled
   2113  *
   2114  * PARAMETERS :
   2115  *   @enable  : flag whether to enable or disable frame sync
   2116  *
   2117  * RETURN     : int32_t type of status
   2118  *              NO_ERROR  -- success
   2119  *              none-zero failure code
   2120  *==========================================================================*/
   2121 int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable)
   2122 {
   2123     return mParameters.setFrameSyncEnabled(enable);
   2124 }
   2125 
   2126 /*===========================================================================
   2127  * FUNCTION   : getRelatedCamSyncInfo
   2128  *
   2129  * DESCRIPTION:returns the related cam sync info for this HWI instance
   2130  *
   2131  * PARAMETERS :none
   2132  *
   2133  * RETURN     : const pointer to cam_sync_related_sensors_event_info_t
   2134  *==========================================================================*/
   2135 const cam_sync_related_sensors_event_info_t*
   2136         QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
   2137 {
   2138     return mParameters.getRelatedCamSyncInfo();
   2139 }
   2140 
   2141 /*===========================================================================
   2142  * FUNCTION   : setRelatedCamSyncInfo
   2143  *
   2144  * DESCRIPTION:sets the related cam sync info for this HWI instance
   2145  *
   2146  * PARAMETERS :
   2147  *   @info  : ptr to related cam info parameters
   2148  *
   2149  * RETURN     : int32_t type of status
   2150  *              NO_ERROR  -- success
   2151  *              none-zero failure code
   2152  *==========================================================================*/
   2153 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
   2154         cam_sync_related_sensors_event_info_t* info)
   2155 {
   2156     if(info) {
   2157         return mParameters.setRelatedCamSyncInfo(info);
   2158     } else {
   2159         return BAD_TYPE;
   2160     }
   2161 }
   2162 
   2163 /*===========================================================================
   2164  * FUNCTION   : getMpoComposition
   2165  *
   2166  * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
   2167  *                    or not
   2168  *
   2169  * PARAMETERS :none
   2170  *
   2171  * RETURN     : bool indicates whether mpo composition is enabled or not
   2172  *==========================================================================*/
   2173 bool QCamera2HardwareInterface::getMpoComposition(void)
   2174 {
   2175     LOGH("MpoComposition:%d ", m_bMpoEnabled);
   2176     return m_bMpoEnabled;
   2177 }
   2178 
   2179 /*===========================================================================
   2180  * FUNCTION   : setMpoComposition
   2181  *
   2182  * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
   2183  *
   2184  * PARAMETERS :
   2185  *   @enable  : indicates whether Mpo composition enabled or not
   2186  *
   2187  * RETURN     : int32_t type of status
   2188  *              NO_ERROR  -- success
   2189  *              none-zero failure code
   2190  *==========================================================================*/
   2191 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
   2192 {
   2193     // By default set Mpo composition to disable
   2194     m_bMpoEnabled = false;
   2195 
   2196     // Enable Mpo composition only if
   2197     // 1) frame sync is ON between two cameras and
   2198     // 2) any advanced features are not enabled (AOST features) and
   2199     // 3) not in recording mode (for liveshot case)
   2200     // 4) flash is not needed
   2201     if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
   2202             !mParameters.isAdvCamFeaturesEnabled() &&
   2203             !mParameters.getRecordingHintValue() &&
   2204             !mFlashNeeded &&
   2205             !isLongshotEnabled()) {
   2206         m_bMpoEnabled = enable;
   2207         LOGH("MpoComposition:%d ", m_bMpoEnabled);
   2208         return NO_ERROR;
   2209     } else {
   2210         return BAD_TYPE;
   2211     }
   2212 }
   2213 
   2214 /*===========================================================================
   2215  * FUNCTION   : getRecordingHintValue
   2216  *
   2217  * DESCRIPTION:function to retrieve recording hint value
   2218  *
   2219  * PARAMETERS :none
   2220  *
   2221  * RETURN     : bool indicates whether recording hint is enabled or not
   2222  *==========================================================================*/
   2223 bool QCamera2HardwareInterface::getRecordingHintValue(void)
   2224 {
   2225     return mParameters.getRecordingHintValue();
   2226 }
   2227 
   2228 /*===========================================================================
   2229  * FUNCTION   : setRecordingHintValue
   2230  *
   2231  * DESCRIPTION:set recording hint value
   2232  *
   2233  * PARAMETERS :
   2234  *   @enable  : video hint value
   2235  *
   2236  * RETURN     : int32_t type of status
   2237  *              NO_ERROR  -- success
   2238  *              none-zero failure code
   2239  *==========================================================================*/
   2240 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
   2241 {
   2242     return mParameters.updateRecordingHintValue(value);
   2243 }
   2244 
   2245 /*===========================================================================
   2246  * FUNCTION   : closeCamera
   2247  *
   2248  * DESCRIPTION: close camera
   2249  *
   2250  * PARAMETERS : none
   2251  *
   2252  * RETURN     : int32_t type of status
   2253  *              NO_ERROR  -- success
   2254  *              none-zero failure code
   2255  *==========================================================================*/
   2256 int QCamera2HardwareInterface::closeCamera()
   2257 {
   2258     int rc = NO_ERROR;
   2259     int i;
   2260     char value[PROPERTY_VALUE_MAX];
   2261     LOGI("E");
   2262     if (!mCameraOpened) {
   2263         return NO_ERROR;
   2264     }
   2265     LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
   2266              mCameraId);
   2267 
   2268     // set open flag to false
   2269     mCameraOpened = false;
   2270 
   2271     // Reset Stream config info
   2272     mParameters.setStreamConfigure(false, false, true);
   2273 
   2274     // deinit Parameters
   2275     mParameters.deinit();
   2276 
   2277     // exit notifier
   2278     m_cbNotifier.exit();
   2279 
   2280     // stop and deinit postprocessor
   2281     waitDeferredWork(mReprocJob);
   2282     // Close the JPEG session
   2283     waitDeferredWork(mJpegJob);
   2284     m_postprocessor.stop();
   2285     deinitJpegHandle();
   2286     m_postprocessor.deinit();
   2287     mInitPProcJob = 0; // reset job id, so pproc can be reinited later
   2288 
   2289     m_thermalAdapter.deinit();
   2290 
   2291     // delete all channels if not already deleted
   2292     for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   2293         if (m_channels[i] != NULL) {
   2294             m_channels[i]->stop();
   2295             delete m_channels[i];
   2296             m_channels[i] = NULL;
   2297         }
   2298     }
   2299 
   2300     //free all pending api results here
   2301     if(m_apiResultList != NULL) {
   2302         api_result_list *apiResultList = m_apiResultList;
   2303         api_result_list *apiResultListNext;
   2304         while (apiResultList != NULL) {
   2305             apiResultListNext = apiResultList->next;
   2306             free(apiResultList);
   2307             apiResultList = apiResultListNext;
   2308         }
   2309     }
   2310 
   2311     rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
   2312     mCameraHandle = NULL;
   2313 
   2314     //Notify display HAL that there is no active camera session
   2315     //but avoid calling the same during bootup. Refer to openCamera
   2316     //for more details.
   2317     property_get("service.bootanim.exit", value, "0");
   2318     if (atoi(value) == 1) {
   2319         pthread_mutex_lock(&gCamLock);
   2320         if (--gNumCameraSessions == 0) {
   2321             setCameraLaunchStatus(false);
   2322         }
   2323         pthread_mutex_unlock(&gCamLock);
   2324     }
   2325 
   2326     if (mExifParams.debug_params) {
   2327         free(mExifParams.debug_params);
   2328         mExifParams.debug_params = NULL;
   2329     }
   2330 
   2331     if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
   2332         LOGD("Failed to release flash for camera id: %d",
   2333                 mCameraId);
   2334     }
   2335 
   2336     LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
   2337          mCameraId, rc);
   2338 
   2339     return rc;
   2340 }
   2341 
   2342 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
   2343 
   2344 
   2345 /*===========================================================================
   2346  * FUNCTION   : getCapabilities
   2347  *
   2348  * DESCRIPTION: query camera capability from back-end
   2349  *
   2350  * PARAMETERS :
   2351  *   @ops        : mm-interface ops structure
   2352  *   @cam_handle  : camera handle for which we need capability
   2353  *
   2354  * RETURN     : ptr type of capability structure
   2355  *              capability for success
   2356  *              NULL for failure
   2357  *==========================================================================*/
   2358 cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
   2359         uint32_t cam_handle)
   2360 {
   2361     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
   2362     int rc = NO_ERROR;
   2363     QCameraHeapMemory *capabilityHeap = NULL;
   2364     cam_capability_t *cap_ptr = NULL;
   2365 
   2366     if (ops == NULL) {
   2367         LOGE("Invalid arguments");
   2368         return NULL;
   2369     }
   2370 
   2371     capabilityHeap = new QCameraHeapMemory(1);
   2372     if (capabilityHeap == NULL) {
   2373         LOGE("creation of capabilityHeap failed");
   2374         return NULL;
   2375     }
   2376 
   2377     /* Allocate memory for capability buffer */
   2378     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t));
   2379     if(rc != OK) {
   2380         LOGE("No memory for capability");
   2381         goto allocate_failed;
   2382     }
   2383 
   2384     /* Map memory for capability buffer */
   2385     memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
   2386 
   2387     cam_buf_map_type_list bufMapList;
   2388     rc = QCameraBufferMaps::makeSingletonBufMapList(
   2389             CAM_MAPPING_BUF_TYPE_CAPABILITY,
   2390             0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
   2391             0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
   2392             bufMapList, capabilityHeap->getPtr(0));
   2393 
   2394     if (rc == NO_ERROR) {
   2395         rc = ops->map_bufs(cam_handle,
   2396                 &bufMapList);
   2397     }
   2398     if(rc < 0) {
   2399         LOGE("failed to map capability buffer");
   2400         goto map_failed;
   2401     }
   2402 
   2403     /* Query Capability */
   2404     rc = ops->query_capability(cam_handle);
   2405     if(rc < 0) {
   2406         LOGE("failed to query capability");
   2407         rc = FAILED_TRANSACTION;
   2408         goto query_failed;
   2409     }
   2410 
   2411     cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
   2412     if (cap_ptr == NULL) {
   2413         LOGE("out of memory");
   2414         rc = NO_MEMORY;
   2415         goto query_failed;
   2416     }
   2417 
   2418     memset(cap_ptr, 0, sizeof(cam_capability_t));
   2419     memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
   2420 
   2421     int index;
   2422     for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
   2423         cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
   2424         p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
   2425         p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
   2426     }
   2427 
   2428 query_failed:
   2429     ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
   2430 map_failed:
   2431     capabilityHeap->deallocate();
   2432 allocate_failed:
   2433     delete capabilityHeap;
   2434 
   2435     if (rc != NO_ERROR) {
   2436         return NULL;
   2437     } else {
   2438         return cap_ptr;
   2439     }
   2440 }
   2441 
   2442 /*===========================================================================
   2443  * FUNCTION   : initCapabilities
   2444  *
   2445  * DESCRIPTION: initialize camera capabilities in static data struct
   2446  *
   2447  * PARAMETERS :
   2448  *   @cameraId  : camera Id
   2449  *
   2450  * RETURN     : int32_t type of status
   2451  *              NO_ERROR  -- success
   2452  *              none-zero failure code
   2453  *==========================================================================*/
   2454 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
   2455         mm_camera_vtbl_t *cameraHandle)
   2456 {
   2457     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_INIT_CAP);
   2458     int rc = 0;
   2459     uint32_t handle = 0;
   2460 
   2461     rc = camera_open((uint8_t)cameraId, &cameraHandle);
   2462     if (rc) {
   2463         LOGE("camera_open failed. rc = %d", rc);
   2464         goto open_failed;
   2465     }
   2466     if (!cameraHandle) {
   2467         LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
   2468         goto open_failed;
   2469     }
   2470 
   2471     handle = get_main_camera_handle(cameraHandle->camera_handle);
   2472     gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
   2473     if (gCamCapability[cameraId] == NULL) {
   2474         rc = FAILED_TRANSACTION;
   2475         goto failed_op;
   2476     }
   2477 
   2478     gCamCapability[cameraId]->camera_index = cameraId;
   2479     if (is_dual_camera_by_idx(cameraId)) {
   2480         handle = get_aux_camera_handle(cameraHandle->camera_handle);
   2481         gCamCapability[cameraId]->aux_cam_cap =
   2482                 getCapabilities(cameraHandle->ops, handle);
   2483         if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
   2484             rc = FAILED_TRANSACTION;
   2485             free(gCamCapability[cameraId]);
   2486             goto failed_op;
   2487         }
   2488 
   2489         // Copy the main camera capability to main_cam_cap struct
   2490         gCamCapability[cameraId]->main_cam_cap =
   2491                 (cam_capability_t *)malloc(sizeof(cam_capability_t));
   2492         if (gCamCapability[cameraId]->main_cam_cap == NULL) {
   2493             LOGE("out of memory");
   2494             rc = NO_MEMORY;
   2495             goto failed_op;
   2496         }
   2497         memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId],
   2498                 sizeof(cam_capability_t));
   2499     }
   2500 failed_op:
   2501     cameraHandle->ops->close_camera(cameraHandle->camera_handle);
   2502     cameraHandle = NULL;
   2503 open_failed:
   2504     return rc;
   2505 }
   2506 
   2507 /*===========================================================================
   2508  * FUNCTION   : getCapabilities
   2509  *
   2510  * DESCRIPTION: query camera capabilities
   2511  *
   2512  * PARAMETERS :
   2513  *   @cameraId  : camera Id
   2514  *   @info      : camera info struct to be filled in with camera capabilities
   2515  *
   2516  * RETURN     : int type of status
   2517  *              NO_ERROR  -- success
   2518  *              none-zero failure code
   2519  *==========================================================================*/
   2520 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
   2521         struct camera_info *info, cam_sync_type_t *p_cam_type)
   2522 {
   2523     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
   2524     int rc = NO_ERROR;
   2525     struct  camera_info *p_info = NULL;
   2526     pthread_mutex_lock(&gCamLock);
   2527     p_info = get_cam_info(cameraId, p_cam_type);
   2528     p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
   2529     p_info->static_camera_characteristics = NULL;
   2530     memcpy(info, p_info, sizeof (struct camera_info));
   2531     pthread_mutex_unlock(&gCamLock);
   2532     return rc;
   2533 }
   2534 
   2535 /*===========================================================================
   2536  * FUNCTION   : getCamHalCapabilities
   2537  *
   2538  * DESCRIPTION: get the HAL capabilities structure
   2539  *
   2540  * PARAMETERS :
   2541  *   @cameraId  : camera Id
   2542  *
   2543  * RETURN     : capability structure of respective camera
   2544  *
   2545  *==========================================================================*/
   2546 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
   2547 {
   2548     return gCamCapability[mCameraId];
   2549 }
   2550 
   2551 /*===========================================================================
   2552  * FUNCTION   : getBufNumForAux
   2553  *
   2554  * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
   2555  *
   2556  * PARAMETERS :
   2557  *   @stream_type  : type of stream
   2558  *
   2559  * RETURN     : number of buffers needed
   2560  * NOTE     :  Based on the use cases and auxillary camera type,
   2561                     we can decide buffer count
   2562  *==========================================================================*/
   2563 uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
   2564 {
   2565     if (!isDualCamera()) {
   2566         return 0;
   2567     }
   2568 
   2569     uint8_t bufferCnt = 1;
   2570     switch (stream_type) {
   2571     case CAM_STREAM_TYPE_PREVIEW:
   2572     case CAM_STREAM_TYPE_VIDEO:
   2573     case CAM_STREAM_TYPE_SNAPSHOT:
   2574     case CAM_STREAM_TYPE_METADATA:
   2575     case CAM_STREAM_TYPE_CALLBACK:
   2576     case CAM_STREAM_TYPE_ANALYSIS:
   2577     case CAM_STREAM_TYPE_POSTVIEW:
   2578     case CAM_STREAM_TYPE_RAW:
   2579     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2580     case CAM_STREAM_TYPE_DEFAULT:
   2581     case CAM_STREAM_TYPE_MAX:
   2582         //For wide & tele, we use same buffer count premary and aux streams.
   2583         bufferCnt = getBufNumRequired(stream_type);
   2584         break;
   2585     default:
   2586         break;
   2587     }
   2588     LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
   2589     return bufferCnt;
   2590 }
   2591 
   2592 /*===========================================================================
   2593  * FUNCTION   : getBufNumRequired
   2594  *
   2595  * DESCRIPTION: return number of stream buffers needed for given stream type
   2596  *
   2597  * PARAMETERS :
   2598  *   @stream_type  : type of stream
   2599  *
   2600  * RETURN     : number of buffers needed
   2601  *==========================================================================*/
   2602 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
   2603 {
   2604     int bufferCnt = 0;
   2605     int minCaptureBuffers = mParameters.getNumOfSnapshots();
   2606     char value[PROPERTY_VALUE_MAX];
   2607     bool raw_yuv = false;
   2608     int persist_cnt = 0;
   2609     int minPrevFps, maxPrevFps;
   2610 
   2611     int zslQBuffers = mParameters.getZSLQueueDepth();
   2612 
   2613     int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
   2614                             CAMERA_MIN_JPEG_ENCODING_BUFFERS;
   2615 
   2616     int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
   2617                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2618                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2619                        mParameters.getNumOfExtraBuffersForImageProc() +
   2620                        EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2621 
   2622     int minUndequeCount = 0;
   2623     if (!isNoDisplayMode()) {
   2624         if(mPreviewWindow != NULL) {
   2625             if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
   2626                 != 0) {
   2627                 LOGW("get_min_undequeued_buffer_count  failed");
   2628                 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
   2629                 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
   2630                 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
   2631             }
   2632         } else {
   2633             //preview window might not be set at this point. So, query directly
   2634             //from BufferQueue implementation of gralloc buffers.
   2635             //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
   2636             //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
   2637             minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
   2638         }
   2639         if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
   2640             // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
   2641             // and so change the MACRO as per minUndequeCount
   2642             LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
   2643                      minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
   2644         }
   2645     }
   2646 
   2647     LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
   2648             "maxStreamBuf = %d minUndequeCount = %d",
   2649             minCaptureBuffers, zslQBuffers, minCircularBufNum,
   2650             maxStreamBuf, minUndequeCount);
   2651     // Get buffer count for the particular stream type
   2652     switch (stream_type) {
   2653     case CAM_STREAM_TYPE_PREVIEW:
   2654         {
   2655             if (mParameters.isZSLMode()) {
   2656                 // We need to add two extra streming buffers to add
   2657                 // flexibility in forming matched super buf in ZSL queue.
   2658                 // with number being 'zslQBuffers + minCircularBufNum'
   2659                 // we see preview buffers sometimes get dropped at CPP
   2660                 // and super buf is not forming in ZSL Q for long time.
   2661 
   2662                 bufferCnt = zslQBuffers + minCircularBufNum +
   2663                         mParameters.getNumOfExtraBuffersForImageProc() +
   2664                         mParameters.getNumOfExtraBuffersForPreview() +
   2665                         mParameters.getNumOfExtraHDRInBufsIfNeeded();
   2666                 if (isDualCamera()) {
   2667                     bufferCnt += zslQBuffers;
   2668                 }
   2669             } else {
   2670                 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
   2671                         mParameters.getMaxUnmatchedFramesInQueue() +
   2672                         mParameters.getNumOfExtraBuffersForPreview();
   2673             }
   2674             // ISP allocates native preview buffers and so reducing same from HAL allocation
   2675             if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
   2676                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2677 
   2678             // Extra ZSL preview frames are not needed for HFR case.
   2679             // Thumbnail will not be derived from preview for HFR live snapshot case.
   2680             if ((mParameters.getRecordingHintValue() == true)
   2681                     && (!mParameters.isHfrMode())) {
   2682                 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2683             }
   2684             //Adding Extra preview buffers for 60FPS usecase.
   2685             mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
   2686             if (maxPrevFps > CAMERA_DEFAULT_FPS) {
   2687                 bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
   2688             }
   2689 
   2690             // Add the display minUndequeCount count on top of camera requirement
   2691             bufferCnt += minUndequeCount;
   2692 
   2693             property_get("persist.camera.preview_yuv", value, "0");
   2694             persist_cnt = atoi(value);
   2695             if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2696                     && (bufferCnt < persist_cnt)) {
   2697                 bufferCnt = persist_cnt;
   2698             }
   2699         }
   2700         break;
   2701     case CAM_STREAM_TYPE_POSTVIEW:
   2702         {
   2703             bufferCnt = minCaptureBuffers +
   2704                         mParameters.getMaxUnmatchedFramesInQueue() +
   2705                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2706                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2707                         mParameters.getNumOfExtraBuffersForImageProc();
   2708 
   2709             if (bufferCnt > maxStreamBuf) {
   2710                 bufferCnt = maxStreamBuf;
   2711             }
   2712             bufferCnt += minUndequeCount;
   2713         }
   2714         break;
   2715     case CAM_STREAM_TYPE_SNAPSHOT:
   2716         {
   2717             if (mParameters.isZSLMode() || mLongshotEnabled) {
   2718                 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
   2719                         !mLongshotEnabled) {
   2720                     // Single ZSL snapshot case
   2721                     bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
   2722                             mParameters.getNumOfExtraBuffersForImageProc();
   2723                 } else {
   2724                     // ZSL Burst or Longshot case
   2725                     bufferCnt = zslQBuffers + minCircularBufNum +
   2726                             mParameters.getNumOfExtraBuffersForImageProc();
   2727                 }
   2728                 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
   2729                     //ISP allocates native buffers in YUV case
   2730                     bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2731                 }
   2732                 if (isDualCamera()) {
   2733                     bufferCnt += zslQBuffers;
   2734                 }
   2735             } else {
   2736                 bufferCnt = minCaptureBuffers +
   2737                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2738                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2739                             mParameters.getNumOfExtraBuffersForImageProc();
   2740 
   2741                 if (bufferCnt > maxStreamBuf) {
   2742                     bufferCnt = maxStreamBuf;
   2743                 }
   2744             }
   2745         }
   2746         break;
   2747     case CAM_STREAM_TYPE_RAW:
   2748         property_get("persist.camera.raw_yuv", value, "0");
   2749         raw_yuv = atoi(value) > 0 ? true : false;
   2750 
   2751         if (isRdiMode() || raw_yuv || isSecureMode()) {
   2752             bufferCnt = zslQBuffers + minCircularBufNum;
   2753         } else if (mParameters.isZSLMode()) {
   2754             bufferCnt = zslQBuffers + minCircularBufNum;
   2755             if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
   2756                 //ISP allocates native buffers in YUV case
   2757                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2758             }
   2759 
   2760         } else {
   2761             bufferCnt = minCaptureBuffers +
   2762                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2763                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2764                         mParameters.getNumOfExtraBuffersForImageProc();
   2765 
   2766             if (bufferCnt > maxStreamBuf) {
   2767                 bufferCnt = maxStreamBuf;
   2768             }
   2769         }
   2770 
   2771         property_get("persist.camera.preview_raw", value, "0");
   2772         persist_cnt = atoi(value);
   2773         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2774                 && (bufferCnt < persist_cnt)) {
   2775             bufferCnt = persist_cnt;
   2776         }
   2777         property_get("persist.camera.video_raw", value, "0");
   2778         persist_cnt = atoi(value);
   2779         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2780                 && (bufferCnt < persist_cnt)) {
   2781             bufferCnt = persist_cnt;
   2782         }
   2783 
   2784         break;
   2785     case CAM_STREAM_TYPE_VIDEO:
   2786         {
   2787             if (mParameters.getBufBatchCount()) {
   2788                 //Video Buffer in case of HFR or camera batching..
   2789                 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
   2790             } else if (mParameters.getVideoBatchSize()) {
   2791                 //Video Buffer count only for HAL to HAL batching.
   2792                 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
   2793                         * mParameters.getVideoBatchSize());
   2794                 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
   2795                     bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
   2796                 }
   2797             } else {
   2798                 // No batching enabled.
   2799                 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
   2800             }
   2801 
   2802             bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
   2803             //if its 4K encoding usecase, then add extra buffer
   2804             cam_dimension_t dim;
   2805             mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
   2806             if (is4k2kResolution(&dim)) {
   2807                  //get additional buffer count
   2808                  property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
   2809                  bufferCnt += atoi(value);
   2810             }
   2811         }
   2812         break;
   2813     case CAM_STREAM_TYPE_METADATA:
   2814         {
   2815             if (mParameters.isZSLMode()) {
   2816                 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
   2817                 bufferCnt = zslQBuffers + minCircularBufNum +
   2818                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2819                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2820                             mParameters.getNumOfExtraBuffersForImageProc() +
   2821                             EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2822                 if (isDualCamera()) {
   2823                     bufferCnt += zslQBuffers;
   2824                 }
   2825             } else {
   2826                 bufferCnt = minCaptureBuffers +
   2827                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2828                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2829                             mParameters.getMaxUnmatchedFramesInQueue() +
   2830                             CAMERA_MIN_STREAMING_BUFFERS +
   2831                             mParameters.getNumOfExtraBuffersForImageProc();
   2832 
   2833                 if (bufferCnt > zslQBuffers + minCircularBufNum) {
   2834                     bufferCnt = zslQBuffers + minCircularBufNum;
   2835                 }
   2836             }
   2837             if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
   2838                 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
   2839             }
   2840         }
   2841         break;
   2842     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2843         {
   2844             bufferCnt = minCaptureBuffers;
   2845             // One of the ubifocus buffers is miscellaneous buffer
   2846             if (mParameters.isUbiRefocus()) {
   2847                 bufferCnt -= 1;
   2848             }
   2849             if (mLongshotEnabled) {
   2850                 bufferCnt = mParameters.getLongshotStages();
   2851             }
   2852         }
   2853         break;
   2854     case CAM_STREAM_TYPE_CALLBACK:
   2855         bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
   2856         break;
   2857     case CAM_STREAM_TYPE_ANALYSIS:
   2858     case CAM_STREAM_TYPE_DEFAULT:
   2859     case CAM_STREAM_TYPE_MAX:
   2860     default:
   2861         bufferCnt = 0;
   2862         break;
   2863     }
   2864 
   2865     LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
   2866     if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
   2867         LOGW("Buffer count %d for stream type %d exceeds limit %d",
   2868                  bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
   2869         return CAM_MAX_NUM_BUFS_PER_STREAM;
   2870     }
   2871 
   2872     return (uint8_t)bufferCnt;
   2873 }
   2874 
   2875 /*===========================================================================
   2876  * FUNCTION   : getStreamRefCount
   2877  *
   2878  * DESCRIPTION: return number of instance of stream of stream type
   2879  *
   2880  * PARAMETERS :
   2881  *   @stream_type  : type of stream
   2882  *   @cam_type      : Type of camera for this stream
   2883  *
   2884  * RETURN     : number of stream instances
   2885  * NOTE      :  Based on the use cases and auxillary camera type,
   2886                      we can decide stream reference count.
   2887                      For example in wide and tele use case, we duplicate all stream
   2888                      streams from premary to auxillary.
   2889  *==========================================================================*/
   2890 uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type,
   2891         uint32_t cam_type)
   2892 {
   2893     uint8_t ref_cnt = 1;
   2894 
   2895     if (cam_type != MM_CAMERA_DUAL_CAM) {
   2896         return ref_cnt;
   2897     }
   2898 
   2899     switch (stream_type) {
   2900     case CAM_STREAM_TYPE_PREVIEW:
   2901     case CAM_STREAM_TYPE_SNAPSHOT:
   2902     case CAM_STREAM_TYPE_VIDEO:
   2903     case CAM_STREAM_TYPE_METADATA:
   2904     case CAM_STREAM_TYPE_ANALYSIS:
   2905     case CAM_STREAM_TYPE_CALLBACK:
   2906         if (isDualCamera()) {
   2907             ref_cnt++;
   2908         }
   2909         break;
   2910     case CAM_STREAM_TYPE_POSTVIEW:
   2911     case CAM_STREAM_TYPE_RAW:
   2912     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2913     case CAM_STREAM_TYPE_DEFAULT:
   2914     case CAM_STREAM_TYPE_MAX:
   2915     default:
   2916         break;
   2917     }
   2918     return ref_cnt;
   2919 }
   2920 
   2921 /*===========================================================================
   2922  * FUNCTION   : getCamHandleForChannel
   2923  *
   2924  * DESCRIPTION: return actual camera handle based on use case
   2925  *
   2926  * PARAMETERS :
   2927  *   @ch_type  : type of channel
   2928  *
   2929  * RETURN     : uint32_t type camera handle
   2930  * NOTE :  Based on the use cases and auxillary camera type, we can decide cam handle for channel.
   2931                  Incase, we want to avoid any channel for auxillary camera, we can decide here
   2932  *==========================================================================*/
   2933 uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
   2934 {
   2935     uint32_t handle = 0;
   2936     if (!isDualCamera()) {
   2937         return mCameraHandle->camera_handle;
   2938     }
   2939 
   2940     /*Based on the use case, decide camera handle for channel*/
   2941     switch (ch_type) {
   2942     case QCAMERA_CH_TYPE_ZSL:
   2943     case QCAMERA_CH_TYPE_CAPTURE:
   2944     case QCAMERA_CH_TYPE_PREVIEW:
   2945     case QCAMERA_CH_TYPE_VIDEO:
   2946     case QCAMERA_CH_TYPE_SNAPSHOT:
   2947     case QCAMERA_CH_TYPE_RAW:
   2948     case QCAMERA_CH_TYPE_METADATA:
   2949     case QCAMERA_CH_TYPE_ANALYSIS:
   2950     case QCAMERA_CH_TYPE_CALLBACK:
   2951     case QCAMERA_CH_TYPE_MAX:
   2952     default:
   2953         handle = mCameraHandle->camera_handle;
   2954         break;
   2955     case QCAMERA_CH_TYPE_REPROCESSING:
   2956         if (!mParameters.isDCmAsymmetricSnapMode()) {
   2957             handle = get_main_camera_handle(mCameraHandle->camera_handle);
   2958         } else {
   2959             /*In Asymmetric mode, we create 2 reproc channels. But
   2960                      one stream is added per channel */
   2961             handle = mCameraHandle->camera_handle;
   2962         }
   2963         break;
   2964     }
   2965     return handle;
   2966 }
   2967 
   2968 /*===========================================================================
   2969  * FUNCTION   : allocateStreamBuf
   2970  *
   2971  * DESCRIPTION: alocate stream buffers
   2972  *
   2973  * PARAMETERS :
   2974  *   @stream_type  : type of stream
   2975  *   @size         : size of buffer
   2976  *   @stride       : stride of buffer
   2977  *   @scanline     : scanline of buffer
   2978  *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
   2979  *                   could be modified during allocation if more buffers needed
   2980  *
   2981  * RETURN     : ptr to a memory obj that holds stream buffers.
   2982  *              NULL if failed
   2983  *==========================================================================*/
   2984 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
   2985         cam_stream_type_t stream_type, size_t size, int stride, int scanline,
   2986         uint8_t &bufferCnt)
   2987 {
   2988     int rc = NO_ERROR;
   2989     QCameraMemory *mem = NULL;
   2990     bool bCachedMem = QCAMERA_ION_USE_CACHE;
   2991     bool bPoolMem = false;
   2992     char value[PROPERTY_VALUE_MAX];
   2993     property_get("persist.camera.mem.usepool", value, "1");
   2994     if (atoi(value) == 1) {
   2995         bPoolMem = true;
   2996     }
   2997 
   2998     // Allocate stream buffer memory object
   2999     switch (stream_type) {
   3000     case CAM_STREAM_TYPE_PREVIEW:
   3001         {
   3002             if (isNoDisplayMode()) {
   3003                 mem = new QCameraStreamMemory(mGetMemory,
   3004                         mCallbackCookie,
   3005                         bCachedMem,
   3006                         (bPoolMem) ? &m_memoryPool : NULL,
   3007                         stream_type);
   3008             } else {
   3009                 cam_dimension_t dim;
   3010                 int minFPS, maxFPS;
   3011                 QCameraGrallocMemory *grallocMemory = NULL;
   3012 
   3013                 if (isSecureMode()) {
   3014                     grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie, QCAMERA_MEM_TYPE_SECURE);
   3015                 }else {
   3016                     grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
   3017                 }
   3018 
   3019                 mParameters.getStreamDimension(stream_type, dim);
   3020                 /* we are interested only in maxfps here */
   3021                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   3022                 int usage = 0;
   3023                 if(mParameters.isUBWCEnabled()) {
   3024                     cam_format_t fmt;
   3025                     mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
   3026                     if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   3027                         usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
   3028                     }
   3029                 }
   3030                 if (grallocMemory) {
   3031                     grallocMemory->setMappable(
   3032                             CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
   3033                     grallocMemory->setWindowInfo(mPreviewWindow,
   3034                             dim.width,dim.height, stride, scanline,
   3035                             mParameters.getPreviewHalPixelFormat(),
   3036                             maxFPS, usage);
   3037                     pthread_mutex_lock(&mGrallocLock);
   3038                     if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
   3039                         mEnqueuedBuffers = (bufferCnt -
   3040                                 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
   3041                     } else {
   3042                         mEnqueuedBuffers = 0;
   3043                     }
   3044                     pthread_mutex_unlock(&mGrallocLock);
   3045                 }
   3046                 mem = grallocMemory;
   3047             }
   3048         }
   3049         break;
   3050     case CAM_STREAM_TYPE_POSTVIEW:
   3051         {
   3052             if (isNoDisplayMode() || isPreviewRestartEnabled()) {
   3053                 mem = new QCameraStreamMemory(mGetMemory, mCallbackCookie, bCachedMem);
   3054             } else {
   3055                 cam_dimension_t dim;
   3056                 int minFPS, maxFPS;
   3057                 QCameraGrallocMemory *grallocMemory =
   3058                         new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
   3059 
   3060                 mParameters.getStreamDimension(stream_type, dim);
   3061                 /* we are interested only in maxfps here */
   3062                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   3063                 if (grallocMemory) {
   3064                     grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
   3065                             dim.height, stride, scanline,
   3066                             mParameters.getPreviewHalPixelFormat(), maxFPS);
   3067                 }
   3068                 mem = grallocMemory;
   3069             }
   3070         }
   3071         break;
   3072     case CAM_STREAM_TYPE_ANALYSIS:
   3073     case CAM_STREAM_TYPE_SNAPSHOT:
   3074     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3075         mem = new QCameraStreamMemory(mGetMemory,
   3076                 mCallbackCookie,
   3077                 bCachedMem,
   3078                 (bPoolMem) ? &m_memoryPool : NULL,
   3079                 stream_type);
   3080         break;
   3081     case CAM_STREAM_TYPE_RAW:
   3082         if(isSecureMode()) {
   3083             mem = new QCameraStreamMemory(mGetMemory,
   3084                     mCallbackCookie,
   3085                     bCachedMem,
   3086                     (bPoolMem) ? &m_memoryPool : NULL,
   3087                     stream_type,
   3088                     QCAMERA_MEM_TYPE_SECURE);
   3089             LOGH("Allocating %d secure buffers of size %d ", bufferCnt, size);
   3090         } else {
   3091             mem = new QCameraStreamMemory(mGetMemory,
   3092                     mCallbackCookie,
   3093                     bCachedMem,
   3094                     (bPoolMem) ? &m_memoryPool : NULL,
   3095                     stream_type);
   3096         }
   3097         break;
   3098     case CAM_STREAM_TYPE_METADATA:
   3099         {
   3100             if (mMetadataMem == NULL) {
   3101                 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
   3102             } else {
   3103                 mem = mMetadataMem;
   3104                 mMetadataMem = NULL;
   3105 
   3106                 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
   3107                 if (numAdditionalBuffers > 0) {
   3108                     rc = mem->allocateMore(numAdditionalBuffers, size);
   3109                     if (rc != NO_ERROR) {
   3110                         LOGE("Failed to allocate additional buffers, "
   3111                                 "but attempting to proceed.");
   3112                     }
   3113                 }
   3114                 bufferCnt = mem->getCnt();
   3115                 // The memory is already allocated  and initialized, so
   3116                 // simply return here.
   3117                 return mem;
   3118             }
   3119         }
   3120         break;
   3121     case CAM_STREAM_TYPE_VIDEO:
   3122         {
   3123             //Use uncached allocation by default
   3124             if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
   3125                     mParameters.isHighQualityNoiseReductionMode()) {
   3126                 bCachedMem = QCAMERA_ION_USE_CACHE;
   3127             }
   3128             else {
   3129                 bCachedMem = QCAMERA_ION_USE_NOCACHE;
   3130             }
   3131 
   3132             QCameraVideoMemory *videoMemory = NULL;
   3133             int usage = 0;
   3134             cam_format_t fmt;
   3135 
   3136             if (mParameters.getVideoBatchSize()) {
   3137                 videoMemory = new QCameraVideoMemory(
   3138                         mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
   3139                 if (videoMemory == NULL) {
   3140                     LOGE("Out of memory for video batching obj");
   3141                     return NULL;
   3142                 }
   3143                 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
   3144                 if (mParameters.isUBWCEnabled() &&
   3145                         (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
   3146                     usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   3147                 }
   3148                 videoMemory->setVideoInfo(usage, fmt);
   3149                 /*
   3150                 *   numFDs = BATCH size
   3151                 *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
   3152                 */
   3153                 rc = videoMemory->allocateMeta(
   3154                         CAMERA_MIN_VIDEO_BATCH_BUFFERS,
   3155                         mParameters.getVideoBatchSize());
   3156                 if (rc < 0) {
   3157                     delete videoMemory;
   3158                     return NULL;
   3159                 }
   3160             } else {
   3161                 videoMemory =
   3162                         new QCameraVideoMemory(mGetMemory, mCallbackCookie, bCachedMem);
   3163                 if (videoMemory == NULL) {
   3164                     LOGE("Out of memory for video obj");
   3165                     return NULL;
   3166                 }
   3167                 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
   3168                 if (mParameters.isUBWCEnabled() &&
   3169                         (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
   3170                     usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   3171                 }
   3172                 videoMemory->setVideoInfo(usage, fmt);
   3173             }
   3174             mem = videoMemory;
   3175         }
   3176         break;
   3177     case CAM_STREAM_TYPE_CALLBACK:
   3178         mem = new QCameraStreamMemory(mGetMemory,
   3179                 mCallbackCookie,
   3180                 bCachedMem,
   3181                 (bPoolMem) ? &m_memoryPool : NULL,
   3182                 stream_type);
   3183         break;
   3184     case CAM_STREAM_TYPE_DEFAULT:
   3185     case CAM_STREAM_TYPE_MAX:
   3186     default:
   3187         break;
   3188     }
   3189     if (!mem) {
   3190         return NULL;
   3191     }
   3192 
   3193     if (bufferCnt > 0) {
   3194         rc = mem->allocate(bufferCnt, size);
   3195         if (rc < 0) {
   3196             delete mem;
   3197             return NULL;
   3198         }
   3199         bufferCnt = mem->getCnt();
   3200     }
   3201     LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d mEnqueuedBuffers = %d",
   3202             rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem, mEnqueuedBuffers);
   3203     return mem;
   3204 }
   3205 
   3206 /*===========================================================================
   3207  * FUNCTION   : allocateMoreStreamBuf
   3208  *
   3209  * DESCRIPTION: alocate more stream buffers from the memory object
   3210  *
   3211  * PARAMETERS :
   3212  *   @mem_obj      : memory object ptr
   3213  *   @size         : size of buffer
   3214  *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
   3215  *                   output will be the number of total buffers
   3216  *
   3217  * RETURN     : int32_t type of status
   3218  *              NO_ERROR  -- success
   3219  *              none-zero failure code
   3220  *==========================================================================*/
   3221 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
   3222         QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
   3223 {
   3224     int rc = NO_ERROR;
   3225 
   3226     if (bufferCnt > 0) {
   3227         rc = mem_obj->allocateMore(bufferCnt, size);
   3228         bufferCnt = mem_obj->getCnt();
   3229     }
   3230     return rc;
   3231 }
   3232 
   3233 /*===========================================================================
   3234  * FUNCTION   : allocateMiscBuf
   3235  *
   3236  * DESCRIPTION: alocate miscellaneous buffer
   3237  *
   3238  * PARAMETERS :
   3239  *   @streamInfo  : stream info
   3240  *
   3241  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3242  *              NULL if failed
   3243  *==========================================================================*/
   3244 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
   3245         cam_stream_info_t *streamInfo)
   3246 {
   3247     int rc = NO_ERROR;
   3248     uint8_t bufNum = 0;
   3249     size_t bufSize = 0;
   3250     QCameraHeapMemory *miscBuf = NULL;
   3251     cam_feature_mask_t feature_mask =
   3252             streamInfo->reprocess_config.pp_feature_config.feature_mask;
   3253 
   3254     switch (streamInfo->stream_type) {
   3255     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3256         if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
   3257             bufNum = 1;
   3258             bufSize = mParameters.getTPMaxMetaSize();
   3259         } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
   3260             bufNum = 1;
   3261             bufSize = mParameters.getRefocusMaxMetaSize();
   3262         }
   3263         break;
   3264     default:
   3265         break;
   3266     }
   3267 
   3268     if (bufNum && bufSize) {
   3269         miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   3270 
   3271         if (!miscBuf) {
   3272             LOGE("Unable to allocate miscBuf object");
   3273             return NULL;
   3274         }
   3275 
   3276         rc = miscBuf->allocate(bufNum, bufSize);
   3277         if (rc < 0) {
   3278             LOGE("Failed to allocate misc buffer memory");
   3279             delete miscBuf;
   3280             return NULL;
   3281         }
   3282     }
   3283 
   3284     return miscBuf;
   3285 }
   3286 
   3287 /*===========================================================================
   3288  * FUNCTION   : initStreamInfoBuf
   3289  *
   3290  * DESCRIPTION: initialize stream info buffer based on stream type
   3291  *
   3292  * PARAMETERS :
   3293  *   @stream_type  : type of stream
   3294  *   @cam_type      : Camera type in case of dual camera
   3295  *
   3296  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3297  *              NULL if failed
   3298  *==========================================================================*/
   3299 int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
   3300             cam_stream_info_t *streamInfo, uint32_t cam_type)
   3301 {
   3302     int rc = NO_ERROR;
   3303     int32_t dt = 0;
   3304     int32_t vc = 0;
   3305 
   3306     memset(streamInfo, 0, sizeof(cam_stream_info_t));
   3307     streamInfo->stream_type = stream_type;
   3308     rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
   3309     rc = mParameters.getStreamDimension(stream_type, streamInfo->dim, cam_type);
   3310     rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
   3311     streamInfo->num_bufs = getBufNumRequired(stream_type);
   3312     streamInfo->buf_cnt = streamInfo->num_bufs;
   3313     streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   3314     streamInfo->is_secure = NON_SECURE;
   3315     // Initialize cache ops
   3316     if (!m_bOptimizeCacheOps) {
   3317         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_DISABLED;
   3318     } else {
   3319         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_HONOUR_FLAGS;
   3320     }
   3321 
   3322     switch (stream_type) {
   3323     case CAM_STREAM_TYPE_SNAPSHOT:
   3324         if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
   3325             mLongshotEnabled) {
   3326             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   3327         } else {
   3328             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   3329             streamInfo->num_of_burst = (uint8_t)
   3330                     (mParameters.getNumOfSnapshots()
   3331                         + mParameters.getNumOfExtraHDRInBufsIfNeeded()
   3332                         - mParameters.getNumOfExtraHDROutBufsIfNeeded()
   3333                         + mParameters.getNumOfExtraBuffersForImageProc());
   3334         }
   3335         break;
   3336     case CAM_STREAM_TYPE_RAW: {
   3337             char value[PROPERTY_VALUE_MAX];
   3338             bool raw_yuv = false;
   3339             property_get("persist.camera.raw_yuv", value, "0");
   3340             raw_yuv = atoi(value) > 0 ? true : false;
   3341             if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv) || isSecureMode()) {
   3342                 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   3343             } else {
   3344                 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   3345                 streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
   3346             }
   3347             if (isSecureMode()) {
   3348                 streamInfo->is_secure = SECURE;
   3349             } else {
   3350                 streamInfo->is_secure = NON_SECURE;
   3351             }
   3352         }
   3353         if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
   3354             mParameters.updateDtVc(&dt, &vc);
   3355             if (dt)
   3356                 streamInfo->dt = dt;
   3357             streamInfo->vc = vc;
   3358         }
   3359 
   3360         break;
   3361     case CAM_STREAM_TYPE_POSTVIEW:
   3362         if (mLongshotEnabled) {
   3363             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   3364         } else {
   3365             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   3366             streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
   3367                 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
   3368                 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
   3369                 + mParameters.getNumOfExtraBuffersForImageProc());
   3370         }
   3371         break;
   3372     case CAM_STREAM_TYPE_VIDEO:
   3373         streamInfo->dis_enable = mParameters.isDISEnabled();
   3374         if (mParameters.getBufBatchCount()) {
   3375             //Update stream info structure with batch mode info
   3376             streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
   3377             streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
   3378             streamInfo->user_buf_info.size =
   3379                     (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
   3380             cam_fps_range_t pFpsRange;
   3381             mParameters.getHfrFps(pFpsRange);
   3382             streamInfo->user_buf_info.frameInterval =
   3383                     (long)((1000/pFpsRange.video_max_fps) * 1000);
   3384             LOGH("Video Batch Count = %d, interval = %d",
   3385                     streamInfo->user_buf_info.frame_buf_cnt,
   3386                     streamInfo->user_buf_info.frameInterval);
   3387         }
   3388         if (mParameters.getRecordingHintValue()) {
   3389             if(mParameters.isDISEnabled()) {
   3390                 streamInfo->is_type = mParameters.getVideoISType();
   3391             } else {
   3392                 streamInfo->is_type = IS_TYPE_NONE;
   3393             }
   3394         }
   3395         if (mParameters.isSecureMode()) {
   3396             streamInfo->is_secure = SECURE;
   3397         }
   3398         break;
   3399     case CAM_STREAM_TYPE_PREVIEW:
   3400         if (mParameters.getRecordingHintValue()) {
   3401             if(mParameters.isDISEnabled()) {
   3402                 streamInfo->is_type = mParameters.getPreviewISType();
   3403             } else {
   3404                 streamInfo->is_type = IS_TYPE_NONE;
   3405             }
   3406         }
   3407         if (isSecureMode()) {
   3408             streamInfo->is_secure = SECURE;
   3409         } else {
   3410             streamInfo->is_secure = NON_SECURE;
   3411         }
   3412         // If SAT enabled, don't add preview stream to Bundled queue
   3413         if (isDualCamera()) {
   3414             char prop[PROPERTY_VALUE_MAX];
   3415             memset(prop, 0, sizeof(prop));
   3416             bool satEnabledFlag = FALSE;
   3417             property_get("persist.camera.sat.enable", prop, "0");
   3418             satEnabledFlag = atoi(prop);
   3419             if (satEnabledFlag) {
   3420                 streamInfo->noFrameExpected = 1;
   3421             }
   3422         }
   3423         break;
   3424     case CAM_STREAM_TYPE_ANALYSIS:
   3425         streamInfo->noFrameExpected = 1;
   3426         break;
   3427     case CAM_STREAM_TYPE_METADATA:
   3428         streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_CLEAR_FLAGS;
   3429         break;
   3430     default:
   3431         break;
   3432     }
   3433 
   3434     // Update feature mask
   3435     mParameters.updatePpFeatureMask(stream_type);
   3436 
   3437     // Get feature mask
   3438     mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
   3439 
   3440     // Update pp config
   3441     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
   3442         int flipMode = mParameters.getFlipMode(stream_type);
   3443         if (flipMode > 0) {
   3444             streamInfo->pp_config.flip = (uint32_t)flipMode;
   3445         }
   3446     }
   3447     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
   3448         streamInfo->pp_config.sharpness = mParameters.getSharpness();
   3449     }
   3450     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
   3451         streamInfo->pp_config.effect = mParameters.getEffectValue();
   3452     }
   3453 
   3454     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
   3455         streamInfo->pp_config.denoise2d.denoise_enable = 1;
   3456         streamInfo->pp_config.denoise2d.process_plates =
   3457                 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
   3458     }
   3459 
   3460     if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
   3461             CAM_STREAM_TYPE_RAW == stream_type))) {
   3462         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
   3463                 CAM_QCOM_FEATURE_CROP)
   3464             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   3465         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
   3466                 CAM_QCOM_FEATURE_SCALE)
   3467             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   3468     }
   3469     streamInfo->aux_str_info = NULL;
   3470 
   3471     LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
   3472            stream_type, streamInfo->fmt, streamInfo->dim.width,
   3473            streamInfo->dim.height, streamInfo->num_bufs,
   3474            streamInfo->pp_config.feature_mask,
   3475            streamInfo->is_type);
   3476 
   3477     return rc;
   3478 }
   3479 
   3480 /*===========================================================================
   3481  * FUNCTION   : allocateStreamInfoBuf
   3482  *
   3483  * DESCRIPTION: alocate stream info buffer
   3484  *
   3485  * PARAMETERS :
   3486  *   @stream_type  : type of stream
   3487  *   @bufCount       : stream info buffer count
   3488  *   @cam_type     : Camera type in case of dual camera
   3489  *
   3490  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3491  *              NULL if failed
   3492  *==========================================================================*/
   3493 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
   3494         cam_stream_type_t stream_type, uint8_t bufCount, uint32_t cam_type)
   3495 {
   3496     int rc = NO_ERROR;
   3497 
   3498     QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   3499     if (!streamInfoBuf) {
   3500         LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
   3501         return NULL;
   3502     }
   3503 
   3504     if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
   3505         LOGE("buffer count should be lesser than max camera : %d", bufCount);
   3506         return NULL;
   3507     }
   3508     rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t));
   3509     if (rc < 0) {
   3510         LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
   3511         delete streamInfoBuf;
   3512         return NULL;
   3513     }
   3514 
   3515     for (uint8_t i = 0; i < bufCount; i++) {
   3516         cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
   3517         memset(streamInfo, 0, sizeof(cam_stream_info_t));
   3518         rc = initStreamInfoBuf(stream_type, streamInfo, cam_type);
   3519         if (rc < 0) {
   3520             LOGE("initStreamInfoBuf failed");
   3521             delete streamInfoBuf;
   3522             return NULL;
   3523         }
   3524     }
   3525 
   3526     cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
   3527     if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
   3528         cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
   3529         streamInfo->aux_str_info = s_streamInfo;
   3530     }
   3531 
   3532     if (streamInfo->aux_str_info != NULL) {
   3533         /*Update StreamInfo for Aux camera*/
   3534         streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
   3535         streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
   3536         streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
   3537     }
   3538     return streamInfoBuf;
   3539 }
   3540 
   3541 /*===========================================================================
   3542  * FUNCTION   : allocateStreamUserBuf
   3543  *
   3544  * DESCRIPTION: allocate user ptr for stream buffers
   3545  *
   3546  * PARAMETERS :
   3547  *   @streamInfo  : stream info structure
   3548  *
   3549  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3550  *                    NULL if failed
   3551 
   3552  *==========================================================================*/
   3553 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
   3554         cam_stream_info_t *streamInfo)
   3555 {
   3556     int rc = NO_ERROR;
   3557     QCameraMemory *mem = NULL;
   3558     int size = 0;
   3559 
   3560     if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
   3561         LOGE("Stream is not in BATCH mode. Invalid Stream");
   3562         return NULL;
   3563     }
   3564 
   3565     // Allocate stream user buffer memory object
   3566     switch (streamInfo->stream_type) {
   3567     case CAM_STREAM_TYPE_VIDEO: {
   3568         QCameraVideoMemory *video_mem = new QCameraVideoMemory(
   3569                 mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
   3570         if (video_mem == NULL) {
   3571             LOGE("Out of memory for video obj");
   3572             return NULL;
   3573         }
   3574 
   3575         int usage = 0;
   3576         cam_format_t fmt;
   3577         mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
   3578         if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
   3579             usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   3580         }
   3581         video_mem->setVideoInfo(usage, fmt);
   3582 
   3583         /*
   3584         *   numFDs = BATCH size
   3585         *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
   3586         */
   3587         rc = video_mem->allocateMeta(streamInfo->num_bufs,
   3588                 mParameters.getBufBatchCount());
   3589         if (rc < 0) {
   3590             LOGE("allocateMeta failed");
   3591             delete video_mem;
   3592             return NULL;
   3593         }
   3594         mem = static_cast<QCameraMemory *>(video_mem);
   3595     }
   3596     break;
   3597 
   3598     case CAM_STREAM_TYPE_PREVIEW:
   3599     case CAM_STREAM_TYPE_POSTVIEW:
   3600     case CAM_STREAM_TYPE_ANALYSIS:
   3601     case CAM_STREAM_TYPE_SNAPSHOT:
   3602     case CAM_STREAM_TYPE_RAW:
   3603     case CAM_STREAM_TYPE_METADATA:
   3604     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3605     case CAM_STREAM_TYPE_CALLBACK:
   3606         LOGE("Stream type Not supported.for BATCH processing");
   3607     break;
   3608 
   3609     case CAM_STREAM_TYPE_DEFAULT:
   3610     case CAM_STREAM_TYPE_MAX:
   3611     default:
   3612         break;
   3613     }
   3614     if (!mem) {
   3615         LOGE("Failed to allocate mem");
   3616         return NULL;
   3617     }
   3618 
   3619     /*Size of this buffer will be number of batch buffer */
   3620     size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
   3621             CAM_PAD_TO_4K);
   3622 
   3623     LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
   3624 
   3625     if (size > 0) {
   3626         // Allocating one buffer for all batch buffers
   3627         rc = mem->allocate(1, size);
   3628         if (rc < 0) {
   3629             delete mem;
   3630             return NULL;
   3631         }
   3632     }
   3633     return mem;
   3634 }
   3635 
   3636 
   3637 /*===========================================================================
   3638  * FUNCTION   : waitForDeferredAlloc
   3639  *
   3640  * DESCRIPTION: Wait for deferred allocation, if applicable
   3641  *              (applicable only for metadata buffers so far)
   3642  *
   3643  * PARAMETERS :
   3644  *   @stream_type  : type of stream to (possibly) wait for
   3645  *
   3646  * RETURN     : None
   3647  *==========================================================================*/
   3648 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
   3649 {
   3650     if (stream_type == CAM_STREAM_TYPE_METADATA) {
   3651         waitDeferredWork(mMetadataAllocJob);
   3652     }
   3653 }
   3654 
   3655 
   3656 /*===========================================================================
   3657  * FUNCTION   : setPreviewWindow
   3658  *
   3659  * DESCRIPTION: set preview window impl
   3660  *
   3661  * PARAMETERS :
   3662  *   @window  : ptr to window ops table struct
   3663  *
   3664  * RETURN     : int32_t type of status
   3665  *              NO_ERROR  -- success
   3666  *              none-zero failure code
   3667  *==========================================================================*/
   3668 int QCamera2HardwareInterface::setPreviewWindow(
   3669         struct preview_stream_ops *window)
   3670 {
   3671     mPreviewWindow = window;
   3672     return NO_ERROR;
   3673 }
   3674 
   3675 /*===========================================================================
   3676  * FUNCTION   : setCallBacks
   3677  *
   3678  * DESCRIPTION: set callbacks impl
   3679  *
   3680  * PARAMETERS :
   3681  *   @notify_cb  : notify cb
   3682  *   @data_cb    : data cb
   3683  *   @data_cb_timestamp : data cb with time stamp
   3684  *   @get_memory : request memory ops table
   3685  *   @user       : user data ptr
   3686  *
   3687  * RETURN     : int32_t type of status
   3688  *              NO_ERROR  -- success
   3689  *              none-zero failure code
   3690  *==========================================================================*/
   3691 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
   3692                                             camera_data_callback data_cb,
   3693                                             camera_data_timestamp_callback data_cb_timestamp,
   3694                                             camera_request_memory get_memory,
   3695                                             void *user)
   3696 {
   3697     mNotifyCb        = notify_cb;
   3698     mDataCb          = data_cb;
   3699     mDataCbTimestamp = data_cb_timestamp;
   3700     mGetMemory       = get_memory;
   3701     mCallbackCookie  = user;
   3702     m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
   3703     return NO_ERROR;
   3704 }
   3705 
   3706 /*===========================================================================
   3707  * FUNCTION   : setJpegCallBacks
   3708  *
   3709  * DESCRIPTION: set JPEG callbacks impl
   3710  *
   3711  * PARAMETERS :
   3712  *   @jpegCb  : Jpeg callback method
   3713  *   @callbackCookie    : callback cookie
   3714  *
   3715  * RETURN     : int32_t type of status
   3716  *              NO_ERROR  -- success
   3717  *              none-zero failure code
   3718  *==========================================================================*/
   3719 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
   3720                                             void *callbackCookie)
   3721 {
   3722     LOGH("camera id %d", getCameraId());
   3723     mJpegCb        = jpegCb;
   3724     mJpegCallbackCookie  = callbackCookie;
   3725     m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
   3726 }
   3727 
   3728 /*===========================================================================
   3729  * FUNCTION   : enableMsgType
   3730  *
   3731  * DESCRIPTION: enable msg type impl
   3732  *
   3733  * PARAMETERS :
   3734  *   @msg_type  : msg type mask to be enabled
   3735  *
   3736  * RETURN     : int32_t type of status
   3737  *              NO_ERROR  -- success
   3738  *              none-zero failure code
   3739  *==========================================================================*/
   3740 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
   3741 {
   3742     int32_t rc = NO_ERROR;
   3743 
   3744     if (mParameters.isUBWCEnabled()) {
   3745         /*Need Special CALLBACK stream incase application requesting for
   3746               Preview callback  in UBWC case*/
   3747         if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
   3748                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
   3749             // Start callback channel only when preview/zsl channel is active
   3750             QCameraChannel* previewCh = NULL;
   3751             if (isZSLMode() && (getRecordingHintValue() != true)) {
   3752                 previewCh = m_channels[QCAMERA_CH_TYPE_ZSL];
   3753             } else {
   3754                 previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   3755             }
   3756             QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK];
   3757             if ((callbackCh != NULL) &&
   3758                     (previewCh != NULL) && previewCh->isActive()) {
   3759                 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
   3760                 if (rc != NO_ERROR) {
   3761                     LOGE("START Callback Channel failed");
   3762                 }
   3763             }
   3764         }
   3765     }
   3766     mMsgEnabled |= msg_type;
   3767     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
   3768     return rc;
   3769 }
   3770 
   3771 /*===========================================================================
   3772  * FUNCTION   : disableMsgType
   3773  *
   3774  * DESCRIPTION: disable msg type impl
   3775  *
   3776  * PARAMETERS :
   3777  *   @msg_type  : msg type mask to be disabled
   3778  *
   3779  * RETURN     : int32_t type of status
   3780  *              NO_ERROR  -- success
   3781  *              none-zero failure code
   3782  *==========================================================================*/
   3783 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
   3784 {
   3785     int32_t rc = NO_ERROR;
   3786 
   3787     if (mParameters.isUBWCEnabled()) {
   3788         /*STOP CALLBACK STREAM*/
   3789         if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
   3790                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
   3791             // Stop callback channel only if it is active
   3792             if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) &&
   3793                    (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) {
   3794                 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
   3795                 if (rc != NO_ERROR) {
   3796                     LOGE("STOP Callback Channel failed");
   3797                 }
   3798             }
   3799         }
   3800     }
   3801     mMsgEnabled &= ~msg_type;
   3802     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
   3803     return rc;
   3804 }
   3805 
   3806 /*===========================================================================
   3807  * FUNCTION   : msgTypeEnabled
   3808  *
   3809  * DESCRIPTION: impl to determine if certain msg_type is enabled
   3810  *
   3811  * PARAMETERS :
   3812  *   @msg_type  : msg type mask
   3813  *
   3814  * RETURN     : 0 -- not enabled
   3815  *              none 0 -- enabled
   3816  *==========================================================================*/
   3817 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
   3818 {
   3819     return (mMsgEnabled & msg_type);
   3820 }
   3821 
   3822 /*===========================================================================
   3823  * FUNCTION   : msgTypeEnabledWithLock
   3824  *
   3825  * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
   3826  *
   3827  * PARAMETERS :
   3828  *   @msg_type  : msg type mask
   3829  *
   3830  * RETURN     : 0 -- not enabled
   3831  *              none 0 -- enabled
   3832  *==========================================================================*/
   3833 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
   3834 {
   3835     int enabled = 0;
   3836     lockAPI();
   3837     enabled = mMsgEnabled & msg_type;
   3838     unlockAPI();
   3839     return enabled;
   3840 }
   3841 
   3842 /*===========================================================================
   3843  * FUNCTION   : startPreview
   3844  *
   3845  * DESCRIPTION: start preview impl
   3846  *
   3847  * PARAMETERS : none
   3848  *
   3849  * RETURN     : int32_t type of status
   3850  *              NO_ERROR  -- success
   3851  *              none-zero failure code
   3852  *==========================================================================*/
   3853 int QCamera2HardwareInterface::startPreview()
   3854 {
   3855     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW);
   3856     int32_t rc = NO_ERROR;
   3857 
   3858     LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
   3859             mParameters.getRecordingHintValue());
   3860 
   3861     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
   3862 
   3863     updateThermalLevel((void *)&mThermalLevel);
   3864 
   3865     setDisplayFrameSkip();
   3866 
   3867     // start preview stream
   3868     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
   3869         rc = startChannel(QCAMERA_CH_TYPE_ZSL);
   3870     } else if (isSecureMode()) {
   3871         if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
   3872             rc = startChannel(QCAMERA_CH_TYPE_RAW);
   3873         }else {
   3874             rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
   3875         }
   3876     } else {
   3877         rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
   3878     }
   3879 
   3880     if (isDualCamera()) {
   3881         if (rc == NO_ERROR) {
   3882             mParameters.setDeferCamera(CAM_DEFER_PROCESS);
   3883         } else {
   3884             mParameters.setDeferCamera(CAM_DEFER_FLUSH);
   3885         }
   3886     }
   3887 
   3888     if (rc != NO_ERROR) {
   3889         LOGE("failed to start channels");
   3890         m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
   3891         return rc;
   3892     }
   3893 
   3894     if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
   3895             && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
   3896         rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
   3897         if (rc != NO_ERROR) {
   3898             LOGE("failed to start callback stream");
   3899             stopChannel(QCAMERA_CH_TYPE_ZSL);
   3900             stopChannel(QCAMERA_CH_TYPE_PREVIEW);
   3901             m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
   3902             return rc;
   3903         }
   3904     }
   3905 
   3906     updatePostPreviewParameters();
   3907     m_stateMachine.setPreviewCallbackNeeded(true);
   3908 
   3909     // if job id is non-zero, that means the postproc init job is already
   3910     // pending or complete
   3911     if (mInitPProcJob == 0) {
   3912         mInitPProcJob = deferPPInit();
   3913         if (mInitPProcJob == 0) {
   3914             LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
   3915                      mCameraHandle);
   3916             rc = -ENOMEM;
   3917             m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
   3918             return rc;
   3919         }
   3920     }
   3921 
   3922     LOGI("X rc = %d", rc);
   3923     return rc;
   3924 }
   3925 
   3926 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
   3927     // Enable OIS only in Camera mode and 4k2k camcoder mode
   3928     int32_t rc = NO_ERROR;
   3929     rc = mParameters.updateOisValue(1);
   3930     return NO_ERROR;
   3931 }
   3932 
   3933 /*===========================================================================
   3934  * FUNCTION   : stopPreview
   3935  *
   3936  * DESCRIPTION: stop preview impl
   3937  *
   3938  * PARAMETERS : none
   3939  *
   3940  * RETURN     : int32_t type of status
   3941  *              NO_ERROR  -- success
   3942  *              none-zero failure code
   3943  *==========================================================================*/
   3944 int QCamera2HardwareInterface::stopPreview()
   3945 {
   3946     KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOPPREVIEW);
   3947     LOGI("E");
   3948     mNumPreviewFaces = -1;
   3949     mActiveAF = false;
   3950 
   3951     // Disable power Hint for preview
   3952     m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
   3953 
   3954     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
   3955 
   3956     // stop preview stream
   3957     stopChannel(QCAMERA_CH_TYPE_CALLBACK);
   3958     stopChannel(QCAMERA_CH_TYPE_ZSL);
   3959     stopChannel(QCAMERA_CH_TYPE_PREVIEW);
   3960     stopChannel(QCAMERA_CH_TYPE_RAW);
   3961 
   3962     m_cbNotifier.flushPreviewNotifications();
   3963     //add for ts makeup
   3964 #ifdef TARGET_TS_MAKEUP
   3965     ts_makeup_finish();
   3966 #endif
   3967     // delete all channels from preparePreview
   3968     unpreparePreview();
   3969 
   3970     m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_PREVIEW);
   3971     LOGI("X");
   3972     return NO_ERROR;
   3973 }
   3974 
   3975 /*===========================================================================
   3976  * FUNCTION   : storeMetaDataInBuffers
   3977  *
   3978  * DESCRIPTION: enable store meta data in buffers for video frames impl
   3979  *
   3980  * PARAMETERS :
   3981  *   @enable  : flag if need enable
   3982  *
   3983  * RETURN     : int32_t type of status
   3984  *              NO_ERROR  -- success
   3985  *              none-zero failure code
   3986  *==========================================================================*/
   3987 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
   3988 {
   3989     mStoreMetaDataInFrame = enable;
   3990     return NO_ERROR;
   3991 }
   3992 
   3993 /*===========================================================================
   3994  * FUNCTION   : preStartRecording
   3995  *
   3996  * DESCRIPTION: Prepare start recording impl
   3997  *
   3998  * PARAMETERS : none
   3999  *
   4000  * RETURN     : int32_t type of status
   4001  *              NO_ERROR  -- success
   4002  *              none-zero failure code
   4003  *==========================================================================*/
   4004 int QCamera2HardwareInterface::preStartRecording()
   4005 {
   4006     int32_t rc = NO_ERROR;
   4007     LOGH("E");
   4008     if (mParameters.getRecordingHintValue() == false) {
   4009 
   4010         // Give HWI control to restart preview only in single camera mode.
   4011         // In dual-cam mode, this control belongs to muxer.
   4012         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   4013             LOGH("start recording when hint is false, stop preview first");
   4014             stopPreview();
   4015 
   4016             // Set recording hint to TRUE
   4017             mParameters.updateRecordingHintValue(TRUE);
   4018             rc = preparePreview();
   4019             if (rc == NO_ERROR) {
   4020                 rc = startPreview();
   4021             }
   4022         }
   4023         else
   4024         {
   4025             // For dual cam mode, update the flag mPreviewRestartNeeded to true
   4026             // Restart control will be handled by muxer.
   4027             mPreviewRestartNeeded = true;
   4028         }
   4029     }
   4030 
   4031     LOGH("X rc = %d", rc);
   4032     return rc;
   4033 }
   4034 
   4035 /*===========================================================================
   4036  * FUNCTION   : startRecording
   4037  *
   4038  * DESCRIPTION: start recording impl
   4039  *
   4040  * PARAMETERS : none
   4041  *
   4042  * RETURN     : int32_t type of status
   4043  *              NO_ERROR  -- success
   4044  *              none-zero failure code
   4045  *==========================================================================*/
   4046 int QCamera2HardwareInterface::startRecording()
   4047 {
   4048     int32_t rc = NO_ERROR;
   4049 
   4050     LOGI("E");
   4051 
   4052     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
   4053 
   4054     //link meta stream with video channel if low power mode.
   4055     if (isLowPowerMode()) {
   4056         // Find and try to link a metadata stream from preview channel
   4057         QCameraChannel *pMetaChannel = NULL;
   4058         QCameraStream *pMetaStream = NULL;
   4059         QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
   4060 
   4061         if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   4062             pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   4063             uint32_t streamNum = pMetaChannel->getNumOfStreams();
   4064             QCameraStream *pStream = NULL;
   4065             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   4066                 pStream = pMetaChannel->getStreamByIndex(i);
   4067                 if ((NULL != pStream) &&
   4068                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
   4069                     pMetaStream = pStream;
   4070                     break;
   4071                 }
   4072             }
   4073         }
   4074 
   4075         if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   4076             rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
   4077             if (NO_ERROR != rc) {
   4078                 LOGW("Metadata stream link failed %d", rc);
   4079             }
   4080         }
   4081     }
   4082 
   4083     if (rc == NO_ERROR) {
   4084         rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
   4085     }
   4086 
   4087     if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
   4088         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   4089         if (!mParameters.is4k2kVideoResolution()) {
   4090             // Find and try to link a metadata stream from preview channel
   4091             QCameraChannel *pMetaChannel = NULL;
   4092             QCameraStream *pMetaStream = NULL;
   4093 
   4094             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   4095                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   4096                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
   4097                 QCameraStream *pStream = NULL;
   4098                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   4099                     pStream = pMetaChannel->getStreamByIndex(i);
   4100                     if ((NULL != pStream) &&
   4101                             (CAM_STREAM_TYPE_METADATA ==
   4102                             pStream->getMyType())) {
   4103                         pMetaStream = pStream;
   4104                         break;
   4105                     }
   4106                 }
   4107             }
   4108 
   4109             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   4110                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   4111                 if (NO_ERROR != rc) {
   4112                     LOGW("Metadata stream link failed %d", rc);
   4113                 }
   4114             }
   4115         }
   4116         LOGH("START snapshot Channel for TNR processing");
   4117         rc = pChannel->start();
   4118     }
   4119 
   4120     m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
   4121 
   4122     if (rc == NO_ERROR) {
   4123         // Set power Hint for video encoding
   4124         m_perfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0);
   4125     }
   4126 
   4127     LOGI("X rc = %d", rc);
   4128     return rc;
   4129 }
   4130 
   4131 /*===========================================================================
   4132  * FUNCTION   : stopRecording
   4133  *
   4134  * DESCRIPTION: stop recording impl
   4135  *
   4136  * PARAMETERS : none
   4137  *
   4138  * RETURN     : int32_t type of status
   4139  *              NO_ERROR  -- success
   4140  *              none-zero failure code
   4141  *==========================================================================*/
   4142 int QCamera2HardwareInterface::stopRecording()
   4143 {
   4144     LOGI("E");
   4145 
   4146     // Disable power hint for video encoding
   4147     m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE);
   4148 
   4149     m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
   4150 
   4151     // stop snapshot channel
   4152     if (mParameters.isTNRSnapshotEnabled()) {
   4153         LOGH("STOP snapshot Channel for TNR processing");
   4154         stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   4155     }
   4156     int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
   4157 
   4158     m_cbNotifier.flushVideoNotifications();
   4159 
   4160     m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_RECORDING);
   4161 
   4162     LOGI("X rc = %d", rc);
   4163     return rc;
   4164 }
   4165 
   4166 /*===========================================================================
   4167  * FUNCTION   : releaseRecordingFrame
   4168  *
   4169  * DESCRIPTION: return video frame impl
   4170  *
   4171  * PARAMETERS :
   4172  *   @opaque  : ptr to video frame to be returned
   4173  *
   4174  * RETURN     : int32_t type of status
   4175  *              NO_ERROR  -- success
   4176  *              none-zero failure code
   4177  *==========================================================================*/
   4178 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
   4179 {
   4180     int32_t rc = UNKNOWN_ERROR;
   4181     QCameraVideoChannel *pChannel =
   4182             (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
   4183     LOGD("opaque data = %p",opaque);
   4184 
   4185     if(pChannel != NULL) {
   4186         rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
   4187     }
   4188     return rc;
   4189 }
   4190 
   4191 /*===========================================================================
   4192  * FUNCTION   : autoFocus
   4193  *
   4194  * DESCRIPTION: start auto focus impl
   4195  *
   4196  * PARAMETERS : none
   4197  *
   4198  * RETURN     : int32_t type of status
   4199  *              NO_ERROR  -- success
   4200  *              none-zero failure code
   4201  *==========================================================================*/
   4202 int QCamera2HardwareInterface::autoFocus()
   4203 {
   4204     int rc = NO_ERROR;
   4205     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   4206     LOGH("E");
   4207 
   4208     switch (focusMode) {
   4209     case CAM_FOCUS_MODE_AUTO:
   4210     case CAM_FOCUS_MODE_MACRO:
   4211     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   4212     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   4213         mActiveAF = true;
   4214         LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
   4215                 focusMode, m_currentFocusState);
   4216         rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
   4217         break;
   4218     case CAM_FOCUS_MODE_INFINITY:
   4219     case CAM_FOCUS_MODE_FIXED:
   4220     case CAM_FOCUS_MODE_EDOF:
   4221     default:
   4222         LOGI("No ops in focusMode (%d)", focusMode);
   4223         rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
   4224         break;
   4225     }
   4226 
   4227     if (NO_ERROR != rc) {
   4228         mActiveAF = false;
   4229     }
   4230     LOGH("X rc = %d", rc);
   4231     return rc;
   4232 }
   4233 
   4234 /*===========================================================================
   4235  * FUNCTION   : cancelAutoFocus
   4236  *
   4237  * DESCRIPTION: cancel auto focus impl
   4238  *
   4239  * PARAMETERS : none
   4240  *
   4241  * RETURN     : int32_t type of status
   4242  *              NO_ERROR  -- success
   4243  *              none-zero failure code
   4244  *==========================================================================*/
   4245 int QCamera2HardwareInterface::cancelAutoFocus()
   4246 {
   4247     int rc = NO_ERROR;
   4248     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   4249 
   4250     switch (focusMode) {
   4251     case CAM_FOCUS_MODE_AUTO:
   4252     case CAM_FOCUS_MODE_MACRO:
   4253     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   4254     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   4255         mActiveAF = false;
   4256         rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
   4257         break;
   4258     case CAM_FOCUS_MODE_INFINITY:
   4259     case CAM_FOCUS_MODE_FIXED:
   4260     case CAM_FOCUS_MODE_EDOF:
   4261     default:
   4262         LOGD("No ops in focusMode (%d)", focusMode);
   4263         break;
   4264     }
   4265     return rc;
   4266 }
   4267 
   4268 /*===========================================================================
   4269  * FUNCTION   : processUFDumps
   4270  *
   4271  * DESCRIPTION: process UF jpeg dumps for refocus support
   4272  *
   4273  * PARAMETERS :
   4274  *   @evt     : payload of jpeg event, including information about jpeg encoding
   4275  *              status, jpeg size and so on.
   4276  *
   4277  * RETURN     : int32_t type of status
   4278  *              NO_ERROR  -- success
   4279  *              none-zero failure code
   4280  *
   4281  * NOTE       : none
   4282  *==========================================================================*/
   4283 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
   4284 {
   4285    bool ret = true;
   4286    if (mParameters.isUbiRefocus()) {
   4287        int index = (int)getOutputImageCount();
   4288        bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
   4289        char name[FILENAME_MAX];
   4290 
   4291        camera_memory_t *jpeg_mem = NULL;
   4292        omx_jpeg_ouput_buf_t *jpeg_out = NULL;
   4293        size_t dataLen;
   4294        uint8_t *dataPtr;
   4295        if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   4296            LOGE("Init PProc Deferred work failed");
   4297            return false;
   4298        }
   4299        if (!m_postprocessor.getJpegMemOpt()) {
   4300            dataLen = evt->out_data.buf_filled_len;
   4301            dataPtr = evt->out_data.buf_vaddr;
   4302        } else {
   4303            jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
   4304            if (!jpeg_out) {
   4305               LOGE("Null pointer detected");
   4306               return false;
   4307            }
   4308            jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
   4309            if (!jpeg_mem) {
   4310               LOGE("Null pointer detected");
   4311               return false;
   4312            }
   4313            dataPtr = (uint8_t *)jpeg_mem->data;
   4314            dataLen = jpeg_mem->size;
   4315        }
   4316 
   4317        if (allFocusImage)  {
   4318            snprintf(name, sizeof(name), "AllFocusImage");
   4319            index = -1;
   4320        } else {
   4321            snprintf(name, sizeof(name), "%d", 0);
   4322        }
   4323        CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
   4324            dataPtr, dataLen);
   4325        LOGD("Dump the image %d %d allFocusImage %d",
   4326            getOutputImageCount(), index, allFocusImage);
   4327        setOutputImageCount(getOutputImageCount() + 1);
   4328        if (!allFocusImage) {
   4329            ret = false;
   4330        }
   4331    }
   4332    return ret;
   4333 }
   4334 
   4335 /*===========================================================================
   4336  * FUNCTION   : unconfigureAdvancedCapture
   4337  *
   4338  * DESCRIPTION: unconfigure Advanced Capture.
   4339  *
   4340  * PARAMETERS : none
   4341  *
   4342  * RETURN     : int32_t type of status
   4343  *              NO_ERROR  -- success
   4344  *              none-zero failure code
   4345  *==========================================================================*/
   4346 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
   4347 {
   4348     int32_t rc = NO_ERROR;
   4349 
   4350     /*Disable Quadra CFA mode*/
   4351     LOGH("Disabling Quadra CFA mode");
   4352     mParameters.setQuadraCfaMode(false, true);
   4353 
   4354     if (mAdvancedCaptureConfigured) {
   4355 
   4356         mAdvancedCaptureConfigured = false;
   4357 
   4358         if(mIs3ALocked) {
   4359             mParameters.set3ALock(false);
   4360             mIs3ALocked = false;
   4361         }
   4362         if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
   4363             rc = mParameters.setToneMapMode(true, true);
   4364             if (rc != NO_ERROR) {
   4365                 LOGW("Failed to enable tone map during HDR/AEBracketing");
   4366             }
   4367             mHDRBracketingEnabled = false;
   4368             rc = mParameters.stopAEBracket();
   4369         } else if ((mParameters.isChromaFlashEnabled())
   4370                 || (mFlashConfigured && !mLongshotEnabled)
   4371                 || (mLowLightConfigured == true)
   4372                 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4373             rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured);
   4374         } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4375             rc = configureAFBracketing(false);
   4376         } else if (mParameters.isOptiZoomEnabled()) {
   4377             rc = mParameters.setAndCommitZoom(mZoomLevel);
   4378             setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
   4379         } else if (mParameters.isStillMoreEnabled()) {
   4380             cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
   4381             stillmore_config.burst_count = 0;
   4382             mParameters.setStillMoreSettings(stillmore_config);
   4383 
   4384             /* If SeeMore is running, it will handle re-enabling tone map */
   4385             if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
   4386                 rc = mParameters.setToneMapMode(true, true);
   4387                 if (rc != NO_ERROR) {
   4388                     LOGW("Failed to enable tone map during StillMore");
   4389                 }
   4390             }
   4391 
   4392             /* Re-enable Tintless */
   4393             mParameters.setTintless(true);
   4394         } else {
   4395             LOGW("No Advanced Capture feature enabled!!");
   4396             rc = BAD_VALUE;
   4397         }
   4398     }
   4399 
   4400     return rc;
   4401 }
   4402 
   4403 /*===========================================================================
   4404  * FUNCTION   : configureAdvancedCapture
   4405  *
   4406  * DESCRIPTION: configure Advanced Capture.
   4407  *
   4408  * PARAMETERS : none
   4409  *
   4410  * RETURN     : int32_t type of status
   4411  *              NO_ERROR  -- success
   4412  *              none-zero failure code
   4413  *==========================================================================*/
   4414 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
   4415 {
   4416     LOGH("E");
   4417     int32_t rc = NO_ERROR;
   4418 
   4419     rc = mParameters.checkFeatureConcurrency();
   4420     if (rc != NO_ERROR) {
   4421         LOGE("Cannot support Advanced capture modes");
   4422         return rc;
   4423     }
   4424     /*Enable Quadra CFA mode*/
   4425     LOGH("Enabling Quadra CFA mode");
   4426     mParameters.setQuadraCfaMode(true, true);
   4427 
   4428     setOutputImageCount(0);
   4429     mInputCount = 0;
   4430     mAdvancedCaptureConfigured = true;
   4431     /* Display should be disabled for advanced modes */
   4432     bool bSkipDisplay = true;
   4433 
   4434     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
   4435         // no Advance capture settings for Aux camera
   4436         LOGH("X Secondary Camera, no need to process!! ");
   4437         return rc;
   4438     }
   4439 
   4440     /* Do not stop display if in stillmore livesnapshot */
   4441     if (mParameters.isStillMoreEnabled() &&
   4442             mParameters.isSeeMoreEnabled()) {
   4443         bSkipDisplay = false;
   4444     }
   4445     if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4446         rc = configureAFBracketing();
   4447     } else if (mParameters.isOptiZoomEnabled()) {
   4448         rc = configureOptiZoom();
   4449     } else if(mParameters.isHDREnabled()) {
   4450         rc = configureHDRBracketing();
   4451         if (mHDRBracketingEnabled) {
   4452             rc = mParameters.setToneMapMode(false, true);
   4453             if (rc != NO_ERROR) {
   4454                 LOGW("Failed to disable tone map during HDR");
   4455             }
   4456         }
   4457     } else if (mParameters.isAEBracketEnabled()) {
   4458         rc = mParameters.setToneMapMode(false, true);
   4459         if (rc != NO_ERROR) {
   4460             LOGW("Failed to disable tone map during AEBracketing");
   4461         }
   4462         rc = configureAEBracketing();
   4463     } else if (mParameters.isStillMoreEnabled()) {
   4464         bSkipDisplay = false;
   4465         rc = configureStillMore();
   4466     } else if ((mParameters.isChromaFlashEnabled())
   4467             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
   4468             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4469         rc = mParameters.configFrameCapture(TRUE);
   4470         if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) {
   4471             mLowLightConfigured = true;
   4472         }
   4473     } else if (mFlashNeeded && !mLongshotEnabled) {
   4474         rc = mParameters.configFrameCapture(TRUE);
   4475         mFlashConfigured = true;
   4476         bSkipDisplay = false;
   4477     } else {
   4478         LOGH("Advanced Capture feature not enabled!! ");
   4479         mAdvancedCaptureConfigured = false;
   4480         bSkipDisplay = false;
   4481     }
   4482 
   4483     if (m_postprocessor.isHalPPEnabled()) {
   4484         LOGH("HALPP is enabled, check if halpp is needed for current snapshot.");
   4485         configureHalPostProcess();
   4486     }
   4487 
   4488     LOGH("Stop preview temporarily for advanced captures");
   4489     setDisplaySkip(bSkipDisplay);
   4490 
   4491     LOGH("X rc = %d", rc);
   4492     return rc;
   4493 }
   4494 
   4495 /*===========================================================================
   4496  * FUNCTION   : configureAFBracketing
   4497  *
   4498  * DESCRIPTION: configure AF Bracketing.
   4499  *
   4500  * PARAMETERS : none
   4501  *
   4502  * RETURN     : int32_t type of status
   4503  *              NO_ERROR  -- success
   4504  *              none-zero failure code
   4505  *==========================================================================*/
   4506 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
   4507 {
   4508     LOGH("E");
   4509     int32_t rc = NO_ERROR;
   4510     cam_af_bracketing_t *af_bracketing_need;
   4511 
   4512     if (mParameters.isUbiRefocus()) {
   4513         af_bracketing_need =
   4514                 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
   4515     } else {
   4516         af_bracketing_need =
   4517                 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
   4518     }
   4519 
   4520     //Enable AF Bracketing.
   4521     cam_af_bracketing_t afBracket;
   4522     memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
   4523     afBracket.enable = enable;
   4524     afBracket.burst_count = af_bracketing_need->burst_count;
   4525 
   4526     for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
   4527         afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
   4528         LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
   4529     }
   4530     //Send cmd to backend to set AF Bracketing for Ubi Focus.
   4531     rc = mParameters.commitAFBracket(afBracket);
   4532     if ( NO_ERROR != rc ) {
   4533         LOGE("cannot configure AF bracketing");
   4534         return rc;
   4535     }
   4536     if (enable) {
   4537         mParameters.set3ALock(true);
   4538         mIs3ALocked = true;
   4539     }
   4540     LOGH("X rc = %d", rc);
   4541     return rc;
   4542 }
   4543 
   4544 /*===========================================================================
   4545  * FUNCTION   : configureHDRBracketing
   4546  *
   4547  * DESCRIPTION: configure HDR Bracketing.
   4548  *
   4549  * PARAMETERS : none
   4550  *
   4551  * RETURN     : int32_t type of status
   4552  *              NO_ERROR  -- success
   4553  *              none-zero failure code
   4554  *==========================================================================*/
   4555 int32_t QCamera2HardwareInterface::configureHDRBracketing()
   4556 {
   4557     LOGH("E");
   4558     int32_t rc = NO_ERROR;
   4559 
   4560     cam_hdr_bracketing_info_t& hdrBracketingSetting =
   4561             gCamCapability[mCameraId]->hdr_bracketing_setting;
   4562 
   4563     // 'values' should be in "idx1,idx2,idx3,..." format
   4564     uint32_t hdrFrameCount =
   4565             hdrBracketingSetting.num_frames;
   4566     LOGH("HDR values %d, %d frame count: %u",
   4567           (int8_t) hdrBracketingSetting.exp_val.values[0],
   4568           (int8_t) hdrBracketingSetting.exp_val.values[1],
   4569           hdrFrameCount);
   4570 
   4571     // Enable AE Bracketing for HDR
   4572     cam_exp_bracketing_t aeBracket;
   4573     memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
   4574     aeBracket.mode =
   4575         hdrBracketingSetting.exp_val.mode;
   4576 
   4577     if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
   4578         mHDRBracketingEnabled = true;
   4579     }
   4580 
   4581     String8 tmp;
   4582     for (uint32_t i = 0; i < hdrFrameCount; i++) {
   4583         tmp.appendFormat("%d",
   4584             (int8_t) hdrBracketingSetting.exp_val.values[i]);
   4585         tmp.append(",");
   4586     }
   4587     if (mParameters.isHDR1xFrameEnabled()
   4588         && mParameters.isHDR1xExtraBufferNeeded()) {
   4589             tmp.appendFormat("%d", 0);
   4590             tmp.append(",");
   4591     }
   4592 
   4593     if( !tmp.isEmpty() &&
   4594         ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
   4595         //Trim last comma
   4596         memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
   4597         memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
   4598     }
   4599 
   4600     LOGH("HDR config values %s",
   4601           aeBracket.values);
   4602     rc = mParameters.setHDRAEBracket(aeBracket);
   4603     if ( NO_ERROR != rc ) {
   4604         LOGE("cannot configure HDR bracketing");
   4605         return rc;
   4606     }
   4607     LOGH("X rc = %d", rc);
   4608     return rc;
   4609 }
   4610 
   4611 /*===========================================================================
   4612  * FUNCTION   : configureAEBracketing
   4613  *
   4614  * DESCRIPTION: configure AE Bracketing.
   4615  *
   4616  * PARAMETERS : none
   4617  *
   4618  * RETURN     : int32_t type of status
   4619  *              NO_ERROR  -- success
   4620  *              none-zero failure code
   4621  *==========================================================================*/
   4622 int32_t QCamera2HardwareInterface::configureAEBracketing()
   4623 {
   4624     LOGH("E");
   4625     int32_t rc = NO_ERROR;
   4626 
   4627     rc = mParameters.setAEBracketing();
   4628     if ( NO_ERROR != rc ) {
   4629         LOGE("cannot configure AE bracketing");
   4630         return rc;
   4631     }
   4632     LOGH("X rc = %d", rc);
   4633     return rc;
   4634 }
   4635 
   4636 /*===========================================================================
   4637  * FUNCTION   : configureOptiZoom
   4638  *
   4639  * DESCRIPTION: configure Opti Zoom.
   4640  *
   4641  * PARAMETERS : none
   4642  *
   4643  * RETURN     : int32_t type of status
   4644  *              NO_ERROR  -- success
   4645  *              none-zero failure code
   4646  *==========================================================================*/
   4647 int32_t QCamera2HardwareInterface::configureOptiZoom()
   4648 {
   4649     int32_t rc = NO_ERROR;
   4650 
   4651     //store current zoom level.
   4652     mZoomLevel = mParameters.getParmZoomLevel();
   4653 
   4654     //set zoom level to 1x;
   4655     mParameters.setAndCommitZoom(0);
   4656 
   4657     mParameters.set3ALock(true);
   4658     mIs3ALocked = true;
   4659 
   4660     return rc;
   4661 }
   4662 
   4663 /*===========================================================================
   4664  * FUNCTION   : configureStillMore
   4665  *
   4666  * DESCRIPTION: configure StillMore.
   4667  *
   4668  * PARAMETERS : none
   4669  *
   4670  * RETURN     : int32_t type of status
   4671  *              NO_ERROR  -- success
   4672  *              none-zero failure code
   4673  *==========================================================================*/
   4674 int32_t QCamera2HardwareInterface::configureStillMore()
   4675 {
   4676     int32_t rc = NO_ERROR;
   4677     uint8_t burst_cnt = 0;
   4678     cam_still_more_t stillmore_config;
   4679     cam_still_more_t stillmore_cap;
   4680 
   4681     /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
   4682     if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
   4683         rc = mParameters.setToneMapMode(false, true);
   4684         if (rc != NO_ERROR) {
   4685             LOGW("Failed to disable tone map during StillMore");
   4686         }
   4687     }
   4688 
   4689     /* Lock 3A */
   4690     mParameters.set3ALock(true);
   4691     mIs3ALocked = true;
   4692 
   4693     /* Disable Tintless */
   4694     mParameters.setTintless(false);
   4695 
   4696     /* Initialize burst count from capability */
   4697     stillmore_cap = mParameters.getStillMoreCapability();
   4698     burst_cnt = stillmore_cap.max_burst_count;
   4699 
   4700     /* Reconfigure burst count from dynamic scene data */
   4701     cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
   4702     if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
   4703             dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
   4704         burst_cnt = dynamic_img_data.input_count;
   4705     }
   4706 
   4707     /* Reconfigure burst count in the case of liveshot */
   4708     if (mParameters.isSeeMoreEnabled()) {
   4709         burst_cnt = 1;
   4710     }
   4711 
   4712     /* Reconfigure burst count from user input */
   4713     char prop[PROPERTY_VALUE_MAX];
   4714     property_get("persist.camera.imglib.stillmore", prop, "0");
   4715     uint8_t burst_setprop = (uint32_t)atoi(prop);
   4716     if (burst_setprop != 0)  {
   4717        if ((burst_setprop < stillmore_cap.min_burst_count) ||
   4718                (burst_setprop > stillmore_cap.max_burst_count)) {
   4719            burst_cnt = stillmore_cap.max_burst_count;
   4720        } else {
   4721            burst_cnt = burst_setprop;
   4722        }
   4723     }
   4724 
   4725     memset(&stillmore_config, 0, sizeof(cam_still_more_t));
   4726     stillmore_config.burst_count = burst_cnt;
   4727     mParameters.setStillMoreSettings(stillmore_config);
   4728 
   4729     LOGH("Stillmore burst %d", burst_cnt);
   4730 
   4731     return rc;
   4732 }
   4733 
   4734 /*===========================================================================
   4735  * FUNCTION   : configureHalPostProcess
   4736  *
   4737  * DESCRIPTION: config hal postproc (HALPP) for current snapshot.
   4738  *
   4739  * PARAMETERS : none
   4740  *
   4741  * RETURN     : int32_t type of status
   4742  *              NO_ERROR  -- success
   4743  *              none-zero failure code
   4744  *==========================================================================*/
   4745 int32_t QCamera2HardwareInterface::configureHalPostProcess()
   4746 {
   4747     LOGD("E");
   4748     int32_t rc = NO_ERROR;
   4749 
   4750     if (!m_postprocessor.isHalPPEnabled()) {
   4751         m_bNeedHalPP = FALSE;
   4752         return rc;
   4753     }
   4754 
   4755     /* check if halpp is needed in dual camera mode */
   4756     if (isDualCamera()) {
   4757         if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot == TRUE) {
   4758             LOGH("Use HALPP for dual camera bundle snapshot.");
   4759             m_bNeedHalPP = TRUE;
   4760         }
   4761         return rc;
   4762     }
   4763 
   4764     return rc;
   4765     LOGD("X");
   4766 }
   4767 
   4768 
   4769 /*===========================================================================
   4770  * FUNCTION   : stopAdvancedCapture
   4771  *
   4772  * DESCRIPTION: stops advanced capture based on capture type
   4773  *
   4774  * PARAMETERS :
   4775  *   @pChannel : channel.
   4776  *
   4777  * RETURN     : int32_t type of status
   4778  *              NO_ERROR  -- success
   4779  *              none-zero failure code
   4780  *==========================================================================*/
   4781 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
   4782         QCameraPicChannel *pChannel)
   4783 {
   4784     LOGH("stop bracketig");
   4785     int32_t rc = NO_ERROR;
   4786 
   4787     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4788         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
   4789     } else if (mParameters.isChromaFlashEnabled()
   4790             || (mFlashConfigured && !mLongshotEnabled)
   4791             || (mLowLightConfigured == true)
   4792             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4793         rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
   4794         mFlashConfigured = false;
   4795         mLowLightConfigured = false;
   4796     } else if(mParameters.isHDREnabled()
   4797             || mParameters.isAEBracketEnabled()) {
   4798         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
   4799     } else if (mParameters.isOptiZoomEnabled()) {
   4800         rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
   4801     } else if (mParameters.isStillMoreEnabled()) {
   4802         LOGH("stopAdvancedCapture not needed for StillMore");
   4803     } else {
   4804         LOGH("No Advanced Capture feature enabled!");
   4805         rc = BAD_VALUE;
   4806     }
   4807 
   4808     m_bNeedHalPP = FALSE;
   4809     return rc;
   4810 }
   4811 
   4812 /*===========================================================================
   4813  * FUNCTION   : startAdvancedCapture
   4814  *
   4815  * DESCRIPTION: starts advanced capture based on capture type
   4816  *
   4817  * PARAMETERS :
   4818  *   @pChannel : channel.
   4819  *
   4820  * RETURN     : int32_t type of status
   4821  *              NO_ERROR  -- success
   4822  *              none-zero failure code
   4823  *==========================================================================*/
   4824 int32_t QCamera2HardwareInterface::startAdvancedCapture(
   4825         QCameraPicChannel *pChannel)
   4826 {
   4827     LOGH("Start bracketing");
   4828     int32_t rc = NO_ERROR;
   4829 
   4830     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4831         rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
   4832     } else if (mParameters.isOptiZoomEnabled()) {
   4833         rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
   4834     } else if (mParameters.isStillMoreEnabled()) {
   4835         LOGH("startAdvancedCapture not needed for StillMore");
   4836     } else if (mParameters.isHDREnabled()
   4837             || mParameters.isAEBracketEnabled()) {
   4838         rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
   4839     } else if (mParameters.isChromaFlashEnabled()
   4840             || (mFlashNeeded && !mLongshotEnabled)
   4841             || (mLowLightConfigured == true)
   4842             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4843         cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
   4844         rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
   4845     } else {
   4846         LOGE("No Advanced Capture feature enabled!");
   4847         rc = BAD_VALUE;
   4848     }
   4849     return rc;
   4850 }
   4851 
   4852 /*===========================================================================
   4853  * FUNCTION   : preTakePicture
   4854  *
   4855  * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
   4856  *
   4857  * PARAMETERS : none
   4858  *
   4859  * RETURN     : int32_t type of status
   4860  *              NO_ERROR  -- success
   4861  *              none-zero failure code
   4862  *==========================================================================*/
   4863 int QCamera2HardwareInterface::preTakePicture()
   4864 {
   4865     int32_t rc = NO_ERROR;
   4866     LOGH("E");
   4867     if (mParameters.getRecordingHintValue() == true) {
   4868 
   4869         // Give HWI control to restart preview only in single camera mode.
   4870         // In dual-cam mode, this control belongs to muxer.
   4871         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   4872             LOGH("restart preview if rec hint is true and preview is running");
   4873             stopPreview();
   4874             mParameters.updateRecordingHintValue(FALSE);
   4875             // start preview again
   4876             rc = preparePreview();
   4877             if (rc == NO_ERROR) {
   4878                 rc = startPreview();
   4879                 if (rc != NO_ERROR) {
   4880                     unpreparePreview();
   4881                 }
   4882             }
   4883         }
   4884         else
   4885         {
   4886             // For dual cam mode, update the flag mPreviewRestartNeeded to true
   4887             // Restart control will be handled by muxer.
   4888             mPreviewRestartNeeded = true;
   4889         }
   4890     }
   4891 
   4892     LOGH("X rc = %d", rc);
   4893     return rc;
   4894 }
   4895 
   4896 /*===========================================================================
   4897  * FUNCTION   : takePicture
   4898  *
   4899  * DESCRIPTION: take picture impl
   4900  *
   4901  * PARAMETERS : none
   4902  *
   4903  * RETURN     : int32_t type of status
   4904  *              NO_ERROR  -- success
   4905  *              none-zero failure code
   4906  *==========================================================================*/
   4907 int QCamera2HardwareInterface::takePicture()
   4908 {
   4909     int rc = NO_ERROR;
   4910 
   4911     // Get total number for snapshots (retro + regular)
   4912     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
   4913     // Get number of retro-active snapshots
   4914     uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
   4915     LOGH("E");
   4916 
   4917     //Set rotation value from user settings as Jpeg rotation
   4918     //to configure back-end modules.
   4919     mParameters.setJpegRotation(mParameters.getRotation());
   4920 
   4921     // Check if retro-active snapshots are not enabled
   4922     if (!isRetroPicture() || !mParameters.isZSLMode()) {
   4923       numRetroSnapshots = 0;
   4924       LOGH("Reset retro snaphot count to zero");
   4925     }
   4926 
   4927     //Do special configure for advanced capture modes.
   4928     rc = configureAdvancedCapture();
   4929     if (rc != NO_ERROR) {
   4930         LOGE("Unsupported capture call");
   4931         return rc;
   4932     }
   4933 
   4934     if (mAdvancedCaptureConfigured) {
   4935         numSnapshots = mParameters.getBurstCountForAdvancedCapture();
   4936     }
   4937 
   4938     if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot) {
   4939         char prop[PROPERTY_VALUE_MAX];
   4940         memset(prop, 0, sizeof(prop));
   4941         property_get("persist.camera.dualfov.jpegnum", prop, "1");
   4942         int dualfov_snap_num = atoi(prop);
   4943 
   4944         memset(prop, 0, sizeof(prop));
   4945         property_get("persist.camera.halpp", prop, "0");
   4946         int halpp_enabled = atoi(prop);
   4947         if(halpp_enabled == 0) {
   4948             dualfov_snap_num = MM_CAMERA_MAX_CAM_CNT;
   4949         }
   4950 
   4951         dualfov_snap_num = (dualfov_snap_num == 0) ? 1 : dualfov_snap_num;
   4952         LOGD("dualfov_snap_num:%d", dualfov_snap_num);
   4953         numSnapshots /= dualfov_snap_num;
   4954     }
   4955 
   4956     LOGI("snap count = %d zsl = %d advanced = %d, active camera:%d",
   4957             numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured, mActiveCameras);
   4958 
   4959     if (mParameters.isZSLMode()) {
   4960         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   4961         QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
   4962         if (NULL != pPicChannel) {
   4963 
   4964             if (mParameters.getofflineRAW()) {
   4965                 startRAWChannel(pPicChannel);
   4966                 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
   4967                 if (pPicChannel == NULL) {
   4968                     LOGE("RAW Channel is NULL in Manual capture mode");
   4969                     stopRAWChannel();
   4970                     return UNKNOWN_ERROR;
   4971                 }
   4972             }
   4973 
   4974             rc = configureOnlineRotation(*pPicChannel);
   4975             if (rc != NO_ERROR) {
   4976                 LOGE("online rotation failed");
   4977                 return rc;
   4978             }
   4979 
   4980             // start postprocessor
   4981             DeferWorkArgs args;
   4982             memset(&args, 0, sizeof(DeferWorkArgs));
   4983 
   4984             args.pprocArgs = pPicChannel;
   4985 
   4986             // No need to wait for mInitPProcJob here, because it was
   4987             // queued in startPreview, and will definitely be processed before
   4988             // mReprocJob can begin.
   4989             mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   4990                     args);
   4991             if (mReprocJob == 0) {
   4992                 LOGE("Failure: Unable to start pproc");
   4993                 return -ENOMEM;
   4994             }
   4995 
   4996             // Check if all preview buffers are mapped before creating
   4997             // a jpeg session as preview stream buffers are queried during the same
   4998             uint8_t numStreams = pChannel->getNumOfStreams();
   4999             QCameraStream *pStream = NULL;
   5000             QCameraStream *pPreviewStream = NULL;
   5001             for (uint8_t i = 0 ; i < numStreams ; i++ ) {
   5002                 pStream = pChannel->getStreamByIndex(i);
   5003                 if (!pStream)
   5004                     continue;
   5005                 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
   5006                     pPreviewStream = pStream;
   5007                     break;
   5008                 }
   5009             }
   5010             if (pPreviewStream != NULL) {
   5011                 Mutex::Autolock l(mMapLock);
   5012                 QCameraMemory *pMemory = pStream->getStreamBufs();
   5013                 if (!pMemory) {
   5014                     LOGE("Error!! pMemory is NULL");
   5015                     return -ENOMEM;
   5016                 }
   5017 
   5018                 uint8_t waitCnt = 2;
   5019                 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
   5020                     LOGL(" Waiting for preview buffers to be mapped");
   5021                     mMapCond.waitRelative(
   5022                             mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
   5023                     LOGL("Wait completed!!");
   5024                     waitCnt--;
   5025                 }
   5026                 // If all buffers are not mapped after retries, assert
   5027                 assert(pMemory->checkIfAllBuffersMapped());
   5028             } else {
   5029                 assert(pPreviewStream);
   5030             }
   5031 
   5032             // Create JPEG session
   5033             mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   5034                     args);
   5035             if (mJpegJob == 0) {
   5036                 LOGE("Failed to queue CREATE_JPEG_SESSION");
   5037                 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5038                         LOGE("Reprocess Deferred work was failed");
   5039                 }
   5040                 m_postprocessor.stop();
   5041                 return -ENOMEM;
   5042             }
   5043 
   5044             if (mAdvancedCaptureConfigured) {
   5045                 rc = startAdvancedCapture(pPicChannel);
   5046                 if (rc != NO_ERROR) {
   5047                     LOGE("cannot start zsl advanced capture");
   5048                     return rc;
   5049                 }
   5050             }
   5051             if (mLongshotEnabled && mPrepSnapRun) {
   5052                 mCameraHandle->ops->start_zsl_snapshot(
   5053                         mCameraHandle->camera_handle,
   5054                         pPicChannel->getMyHandle());
   5055             }
   5056             // If frame sync is ON and it is a SECONDARY camera,
   5057             // we do not need to send the take picture command to interface
   5058             // It will be handled along with PRIMARY camera takePicture request
   5059             mm_camera_req_buf_t buf;
   5060             memset(&buf, 0x0, sizeof(buf));
   5061             if ((!mParameters.isAdvCamFeaturesEnabled() &&
   5062                     !mFlashNeeded &&
   5063                     !isLongshotEnabled() &&
   5064                     isFrameSyncEnabled()) &&
   5065                     (getRelatedCamSyncInfo()->sync_control ==
   5066                     CAM_SYNC_RELATED_SENSORS_ON)) {
   5067                 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
   5068                     buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
   5069                     buf.num_buf_requested = numSnapshots;
   5070                     rc = pPicChannel->takePicture(&buf);
   5071                     if (rc != NO_ERROR) {
   5072                         LOGE("FS_DBG cannot take ZSL picture, stop pproc");
   5073                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5074                             LOGE("Reprocess Deferred work failed");
   5075                             return UNKNOWN_ERROR;
   5076                         }
   5077                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   5078                             LOGE("Jpeg Deferred work failed");
   5079                             return UNKNOWN_ERROR;
   5080                         }
   5081                         m_postprocessor.stop();
   5082                         return rc;
   5083                     }
   5084                     LOGI("PRIMARY camera: send frame sync takePicture!!");
   5085                 }
   5086             } else {
   5087                 buf.type = MM_CAMERA_REQ_SUPER_BUF;
   5088                 buf.num_buf_requested = numSnapshots;
   5089                 buf.num_retro_buf_requested = numRetroSnapshots;
   5090                 rc = pPicChannel->takePicture(&buf);
   5091                 if (rc != NO_ERROR) {
   5092                     LOGE("cannot take ZSL picture, stop pproc");
   5093                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5094                             LOGE("Reprocess Deferred work failed");
   5095                             return UNKNOWN_ERROR;
   5096                         }
   5097                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   5098                             LOGE("Jpeg Deferred work failed");
   5099                             return UNKNOWN_ERROR;
   5100                         }
   5101                     m_postprocessor.stop();
   5102                     return rc;
   5103                 }
   5104             }
   5105         } else {
   5106             LOGE("ZSL channel is NULL");
   5107             return UNKNOWN_ERROR;
   5108         }
   5109     } else {
   5110 
   5111         // start snapshot
   5112         if (mParameters.isJpegPictureFormat() ||
   5113                 mParameters.isNV16PictureFormat() ||
   5114                 mParameters.isNV21PictureFormat()) {
   5115 
   5116             //STOP Preview for Non ZSL use case
   5117             stopPreview();
   5118 
   5119             //Config CAPTURE channels
   5120             rc = declareSnapshotStreams();
   5121             if (NO_ERROR != rc) {
   5122                 return rc;
   5123             }
   5124 
   5125             rc = addCaptureChannel();
   5126             if ((rc == NO_ERROR) &&
   5127                     (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
   5128 
   5129                 if (!mParameters.getofflineRAW()) {
   5130                     rc = configureOnlineRotation(
   5131                         *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
   5132                     if (rc != NO_ERROR) {
   5133                         LOGE("online rotation failed");
   5134                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
   5135                         return rc;
   5136                     }
   5137                 }
   5138 
   5139                 DeferWorkArgs args;
   5140                 memset(&args, 0, sizeof(DeferWorkArgs));
   5141 
   5142                 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
   5143 
   5144                 // No need to wait for mInitPProcJob here, because it was
   5145                 // queued in startPreview, and will definitely be processed before
   5146                 // mReprocJob can begin.
   5147                 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   5148                         args);
   5149                 if (mReprocJob == 0) {
   5150                     LOGE("Failure: Unable to start pproc");
   5151                     return -ENOMEM;
   5152                 }
   5153 
   5154                 // Create JPEG session
   5155                 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   5156                         args);
   5157                 if (mJpegJob == 0) {
   5158                     LOGE("Failed to queue CREATE_JPEG_SESSION");
   5159                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5160                         LOGE("Reprocess Deferred work was failed");
   5161                     }
   5162                     m_postprocessor.stop();
   5163                     return -ENOMEM;
   5164                 }
   5165 
   5166                 // start catpure channel
   5167                 rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
   5168                 if (rc != NO_ERROR) {
   5169                     LOGE("cannot start capture channel");
   5170                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5171                         LOGE("Reprocess Deferred work failed");
   5172                         return UNKNOWN_ERROR;
   5173                     }
   5174                     if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   5175                         LOGE("Jpeg Deferred work failed");
   5176                         return UNKNOWN_ERROR;
   5177                     }
   5178                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
   5179                     return rc;
   5180                 }
   5181 
   5182                 QCameraPicChannel *pCapChannel =
   5183                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
   5184                 if (NULL != pCapChannel) {
   5185                     if (mParameters.isUbiFocusEnabled() ||
   5186                             mParameters.isUbiRefocus() ||
   5187                             mParameters.isChromaFlashEnabled()) {
   5188                         rc = startAdvancedCapture(pCapChannel);
   5189                         if (rc != NO_ERROR) {
   5190                             LOGE("cannot start advanced capture");
   5191                             return rc;
   5192                         }
   5193                     }
   5194                 }
   5195                 if ( mLongshotEnabled ) {
   5196                     rc = longShot();
   5197                     if (NO_ERROR != rc) {
   5198                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5199                             LOGE("Reprocess Deferred work failed");
   5200                             return UNKNOWN_ERROR;
   5201                         }
   5202                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   5203                             LOGE("Jpeg Deferred work failed");
   5204                             return UNKNOWN_ERROR;
   5205                         }
   5206                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
   5207                         return rc;
   5208                     }
   5209                 }
   5210             } else {
   5211                 LOGE("cannot add capture channel");
   5212                 delChannel(QCAMERA_CH_TYPE_CAPTURE);
   5213                 return rc;
   5214             }
   5215         } else {
   5216             // Stop Preview before taking NZSL snapshot
   5217             stopPreview();
   5218 
   5219             rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
   5220             if (NO_ERROR != rc) {
   5221                 LOGE("Raw dimension update failed %d", rc);
   5222                 return rc;
   5223             }
   5224 
   5225             rc = declareSnapshotStreams();
   5226             if (NO_ERROR != rc) {
   5227                 LOGE("RAW stream info configuration failed %d", rc);
   5228                 return rc;
   5229             }
   5230 
   5231             rc = addChannel(QCAMERA_CH_TYPE_RAW);
   5232             if (rc == NO_ERROR) {
   5233                 // start postprocessor
   5234                 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   5235                     LOGE("Reprocess Deferred work failed");
   5236                     return UNKNOWN_ERROR;
   5237                 }
   5238 
   5239                 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
   5240                 if (rc != NO_ERROR) {
   5241                     LOGE("cannot start postprocessor");
   5242                     delChannel(QCAMERA_CH_TYPE_RAW);
   5243                     return rc;
   5244                 }
   5245 
   5246                 rc = startChannel(QCAMERA_CH_TYPE_RAW);
   5247                 if (rc != NO_ERROR) {
   5248                     LOGE("cannot start raw channel");
   5249                     m_postprocessor.stop();
   5250                     delChannel(QCAMERA_CH_TYPE_RAW);
   5251                     return rc;
   5252                 }
   5253             } else {
   5254                 LOGE("cannot add raw channel");
   5255                 return rc;
   5256             }
   5257         }
   5258     }
   5259 
   5260     //When take picture, stop sending preview callbacks to APP
   5261     m_stateMachine.setPreviewCallbackNeeded(false);
   5262     LOGI("X rc = %d", rc);
   5263     return rc;
   5264 }
   5265 
   5266 /*===========================================================================
   5267  * FUNCTION   : configureOnlineRotation
   5268  *
   5269  * DESCRIPTION: Configure backend with expected rotation for snapshot stream
   5270  *
   5271  * PARAMETERS :
   5272  *    @ch     : Channel containing a snapshot stream
   5273  *
   5274  * RETURN     : int32_t type of status
   5275  *              NO_ERROR  -- success
   5276  *              none-zero failure code
   5277  *==========================================================================*/
   5278 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
   5279 {
   5280     int rc = NO_ERROR;
   5281     uint32_t streamId = 0;
   5282     QCameraStream *pStream = NULL;
   5283 
   5284     for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
   5285         QCameraStream *stream = ch.getStreamByIndex(i);
   5286         if ((NULL != stream) &&
   5287                 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
   5288                 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
   5289             pStream = stream;
   5290             break;
   5291         }
   5292     }
   5293 
   5294     if (NULL == pStream) {
   5295         LOGE("No snapshot stream found!");
   5296         return BAD_VALUE;
   5297     }
   5298 
   5299     streamId = pStream->getMyServerID();
   5300     // Update online rotation configuration
   5301     rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
   5302             mParameters.getDeviceRotation());
   5303     if (rc != NO_ERROR) {
   5304         LOGE("addOnlineRotation failed %d", rc);
   5305         return rc;
   5306     }
   5307 
   5308     return rc;
   5309 }
   5310 
   5311 /*===========================================================================
   5312  * FUNCTION   : declareSnapshotStreams
   5313  *
   5314  * DESCRIPTION: Configure backend with expected snapshot streams
   5315  *
   5316  * PARAMETERS : none
   5317  *
   5318  * RETURN     : int32_t type of status
   5319  *              NO_ERROR  -- success
   5320  *              none-zero failure code
   5321  *==========================================================================*/
   5322 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
   5323 {
   5324     int rc = NO_ERROR;
   5325 
   5326     // Update stream info configuration
   5327     rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
   5328     if (rc != NO_ERROR) {
   5329         LOGE("setStreamConfigure failed %d", rc);
   5330         return rc;
   5331     }
   5332 
   5333     return rc;
   5334 }
   5335 
   5336 /*===========================================================================
   5337  * FUNCTION   : longShot
   5338  *
   5339  * DESCRIPTION: Queue one more ZSL frame
   5340  *              in the longshot pipe.
   5341  *
   5342  * PARAMETERS : none
   5343  *
   5344  * RETURN     : int32_t type of status
   5345  *              NO_ERROR  -- success
   5346  *              none-zero failure code
   5347  *==========================================================================*/
   5348 int32_t QCamera2HardwareInterface::longShot()
   5349 {
   5350     int32_t rc = NO_ERROR;
   5351     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
   5352     QCameraPicChannel *pChannel = NULL;
   5353 
   5354     if (mParameters.isZSLMode()) {
   5355         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   5356     } else {
   5357         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
   5358     }
   5359 
   5360     if (NULL != pChannel) {
   5361         mm_camera_req_buf_t buf;
   5362         memset(&buf, 0x0, sizeof(buf));
   5363         buf.type = MM_CAMERA_REQ_SUPER_BUF;
   5364         buf.num_buf_requested = numSnapshots;
   5365         rc = pChannel->takePicture(&buf);
   5366     } else {
   5367         LOGE("Capture channel not initialized!");
   5368         rc = NO_INIT;
   5369         goto end;
   5370     }
   5371 
   5372 end:
   5373     return rc;
   5374 }
   5375 
   5376 /*===========================================================================
   5377  * FUNCTION   : stopCaptureChannel
   5378  *
   5379  * DESCRIPTION: Stops capture channel
   5380  *
   5381  * PARAMETERS :
   5382  *   @destroy : Set to true to stop and delete camera channel.
   5383  *              Set to false to only stop capture channel.
   5384  *
   5385  * RETURN     : int32_t type of status
   5386  *              NO_ERROR  -- success
   5387  *              none-zero failure code
   5388  *==========================================================================*/
   5389 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
   5390 {
   5391     int rc = NO_ERROR;
   5392     if (mParameters.isJpegPictureFormat() ||
   5393         mParameters.isNV16PictureFormat() ||
   5394         mParameters.isNV21PictureFormat()) {
   5395         mParameters.setQuadraCfaMode(false, true);
   5396         rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
   5397         if (destroy && (NO_ERROR == rc)) {
   5398             // Destroy camera channel but dont release context
   5399             waitDeferredWork(mJpegJob);
   5400             rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
   5401         }
   5402     }
   5403 
   5404     return rc;
   5405 }
   5406 
   5407 /*===========================================================================
   5408  * FUNCTION   : cancelPicture
   5409  *
   5410  * DESCRIPTION: cancel picture impl
   5411  *
   5412  * PARAMETERS : none
   5413  *
   5414  * RETURN     : int32_t type of status
   5415  *              NO_ERROR  -- success
   5416  *              none-zero failure code
   5417  *==========================================================================*/
   5418 int QCamera2HardwareInterface::cancelPicture()
   5419 {
   5420     waitDeferredWork(mReprocJob);
   5421     waitDeferredWork(mJpegJob);
   5422 
   5423     //stop post processor
   5424     m_postprocessor.stop();
   5425 
   5426     unconfigureAdvancedCapture();
   5427     LOGH("Enable display frames again");
   5428     setDisplaySkip(FALSE);
   5429 
   5430     if (mParameters.isZSLMode()) {
   5431         QCameraPicChannel *pPicChannel = NULL;
   5432         if (mParameters.getofflineRAW()) {
   5433             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
   5434         } else {
   5435             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   5436         }
   5437         if (NULL != pPicChannel) {
   5438             pPicChannel->cancelPicture();
   5439             stopRAWChannel();
   5440             stopAdvancedCapture(pPicChannel);
   5441         }
   5442     } else {
   5443 
   5444         // normal capture case
   5445         if (mParameters.isJpegPictureFormat() ||
   5446             mParameters.isNV16PictureFormat() ||
   5447             mParameters.isNV21PictureFormat()) {
   5448             stopChannel(QCAMERA_CH_TYPE_CAPTURE);
   5449             delChannel(QCAMERA_CH_TYPE_CAPTURE);
   5450         } else {
   5451             stopChannel(QCAMERA_CH_TYPE_RAW);
   5452             delChannel(QCAMERA_CH_TYPE_RAW);
   5453         }
   5454     }
   5455 
   5456     return NO_ERROR;
   5457 }
   5458 
   5459 /*===========================================================================
   5460  * FUNCTION   : captureDone
   5461  *
   5462  * DESCRIPTION: Function called when the capture is completed before encoding
   5463  *
   5464  * PARAMETERS : none
   5465  *
   5466  * RETURN     : none
   5467  *==========================================================================*/
   5468 void QCamera2HardwareInterface::captureDone()
   5469 {
   5470     qcamera_sm_internal_evt_payload_t *payload =
   5471        (qcamera_sm_internal_evt_payload_t *)
   5472        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   5473     if (NULL != payload) {
   5474         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   5475         payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
   5476         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   5477         if (rc != NO_ERROR) {
   5478             LOGE("processEvt ZSL capture done failed");
   5479             free(payload);
   5480             payload = NULL;
   5481         }
   5482     } else {
   5483         LOGE("No memory for ZSL capture done event");
   5484     }
   5485 }
   5486 
   5487 /*===========================================================================
   5488  * FUNCTION   : Live_Snapshot_thread
   5489  *
   5490  * DESCRIPTION: Seperate thread for taking live snapshot during recording
   5491  *
   5492  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
   5493  *
   5494  * RETURN     : none
   5495  *==========================================================================*/
   5496 void* Live_Snapshot_thread (void* data)
   5497 {
   5498 
   5499     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
   5500     if (!hw) {
   5501         LOGE("take_picture_thread: NULL camera device");
   5502         return (void *)BAD_VALUE;
   5503     }
   5504     if (hw->bLiveSnapshot) {
   5505         hw->takeLiveSnapshot_internal();
   5506     } else {
   5507         hw->cancelLiveSnapshot_internal();
   5508     }
   5509     return (void* )NULL;
   5510 }
   5511 
   5512 /*===========================================================================
   5513  * FUNCTION   : Int_Pic_thread
   5514  *
   5515  * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
   5516  *
   5517  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
   5518  *
   5519  * RETURN     : none
   5520  *==========================================================================*/
   5521 void* Int_Pic_thread (void* data)
   5522 {
   5523     int rc = NO_ERROR;
   5524 
   5525     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
   5526 
   5527     if (!hw) {
   5528         LOGE("take_picture_thread: NULL camera device");
   5529         return (void *)BAD_VALUE;
   5530     }
   5531 
   5532     bool JpegMemOpt = false;
   5533     char raw_format[PROPERTY_VALUE_MAX];
   5534 
   5535     memset(raw_format, 0, sizeof(raw_format));
   5536 
   5537     rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
   5538     if (rc == NO_ERROR) {
   5539         hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
   5540     } else {
   5541         //Snapshot attempt not successful, we need to do cleanup here
   5542         hw->clearIntPendingEvents();
   5543     }
   5544 
   5545     return (void* )NULL;
   5546 }
   5547 
   5548 /*===========================================================================
   5549  * FUNCTION   : takeLiveSnapshot
   5550  *
   5551  * DESCRIPTION: take live snapshot during recording
   5552  *
   5553  * PARAMETERS : none
   5554  *
   5555  * RETURN     : int32_t type of status
   5556  *              NO_ERROR  -- success
   5557  *              none-zero failure code
   5558  *==========================================================================*/
   5559 int QCamera2HardwareInterface::takeLiveSnapshot()
   5560 {
   5561     int rc = NO_ERROR;
   5562     if (mLiveSnapshotThread != 0) {
   5563         pthread_join(mLiveSnapshotThread,NULL);
   5564         mLiveSnapshotThread = 0;
   5565     }
   5566     bLiveSnapshot = true;
   5567     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
   5568     if (!rc) {
   5569         pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
   5570     }
   5571     return rc;
   5572 }
   5573 
   5574 /*===========================================================================
   5575  * FUNCTION   : takePictureInternal
   5576  *
   5577  * DESCRIPTION: take snapshot triggered by backend
   5578  *
   5579  * PARAMETERS : none
   5580  *
   5581  * RETURN     : int32_t type of status
   5582  *              NO_ERROR  -- success
   5583  *              none-zero failure code
   5584  *==========================================================================*/
   5585 int QCamera2HardwareInterface::takePictureInternal()
   5586 {
   5587     int rc = NO_ERROR;
   5588     rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
   5589     if (!rc) {
   5590         pthread_setname_np(mIntPicThread, "CAM_IntPic");
   5591     }
   5592     return rc;
   5593 }
   5594 
   5595 /*===========================================================================
   5596  * FUNCTION   : checkIntPicPending
   5597  *
   5598  * DESCRIPTION: timed wait for jpeg completion event, and send
   5599  *                        back completion event to backend
   5600  *
   5601  * PARAMETERS : none
   5602  *
   5603  * RETURN     : none
   5604  *==========================================================================*/
   5605 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
   5606 {
   5607     bool bSendToBackend = true;
   5608     cam_int_evt_params_t params;
   5609     int rc = NO_ERROR;
   5610 
   5611     struct timespec   ts;
   5612     struct timeval    tp;
   5613     gettimeofday(&tp, NULL);
   5614     ts.tv_sec  = tp.tv_sec + 5;
   5615     ts.tv_nsec = tp.tv_usec * 1000;
   5616 
   5617     if (true == m_bIntJpegEvtPending ||
   5618         (true == m_bIntRawEvtPending)) {
   5619         //Waiting in HAL for snapshot taken notification
   5620         pthread_mutex_lock(&m_int_lock);
   5621         rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
   5622         if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
   5623             //Hit a timeout, or some spurious activity
   5624             bSendToBackend = false;
   5625         }
   5626 
   5627         if (true == m_bIntJpegEvtPending) {
   5628             params.event_type = 0;
   5629             mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
   5630         } else if (true == m_bIntRawEvtPending) {
   5631             params.event_type = 1;
   5632             mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
   5633         }
   5634         pthread_mutex_unlock(&m_int_lock);
   5635 
   5636         if (true == m_bIntJpegEvtPending) {
   5637             //Attempting to restart preview after taking JPEG snapshot
   5638             lockAPI();
   5639             rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
   5640             unlockAPI();
   5641             m_postprocessor.setJpegMemOpt(JpegMemOpt);
   5642         } else if (true == m_bIntRawEvtPending) {
   5643             //Attempting to restart preview after taking RAW snapshot
   5644             stopChannel(QCAMERA_CH_TYPE_RAW);
   5645             delChannel(QCAMERA_CH_TYPE_RAW);
   5646             //restoring the old raw format
   5647             property_set("persist.camera.raw.format", raw_format);
   5648         }
   5649 
   5650         if (true == bSendToBackend) {
   5651             //send event back to server with the file path
   5652             params.dim = m_postprocessor.m_dst_dim;
   5653             memcpy(&params.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
   5654             memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
   5655             params.size = mBackendFileSize;
   5656             rc = mParameters.setIntEvent(params);
   5657         }
   5658 
   5659         clearIntPendingEvents();
   5660     }
   5661 
   5662     return;
   5663 }
   5664 
   5665 /*===========================================================================
   5666  * FUNCTION   : takeBackendPic_internal
   5667  *
   5668  * DESCRIPTION: take snapshot triggered by backend
   5669  *
   5670  * PARAMETERS : none
   5671  *
   5672  * RETURN     : int32_t type of status
   5673  *              NO_ERROR  -- success
   5674  *              none-zero failure code
   5675  *==========================================================================*/
   5676 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
   5677 {
   5678     int rc = NO_ERROR;
   5679     qcamera_api_result_t apiResult;
   5680 
   5681     lockAPI();
   5682     //Set rotation value from user settings as Jpeg rotation
   5683     //to configure back-end modules.
   5684     mParameters.setJpegRotation(mParameters.getRotation());
   5685 
   5686     setRetroPicture(0);
   5687     /* Prepare snapshot in case LED needs to be flashed */
   5688     if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
   5689         // Start Preparing for normal Frames
   5690         LOGH("Start Prepare Snapshot");
   5691         /* Prepare snapshot in case LED needs to be flashed */
   5692         rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
   5693         if (rc == NO_ERROR) {
   5694             waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
   5695             rc = apiResult.status;
   5696         }
   5697         LOGH("Prep Snapshot done rc = %d", rc);
   5698         mPrepSnapRun = true;
   5699     }
   5700     unlockAPI();
   5701 
   5702     if (true == m_bIntJpegEvtPending) {
   5703         //Attempting to take JPEG snapshot
   5704         if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   5705             LOGE("Init PProc Deferred work failed");
   5706             return UNKNOWN_ERROR;
   5707         }
   5708         *JpegMemOpt = m_postprocessor.getJpegMemOpt();
   5709         m_postprocessor.setJpegMemOpt(false);
   5710 
   5711         /* capture */
   5712         lockAPI();
   5713         LOGH("Capturing internal snapshot");
   5714         rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
   5715         if (rc == NO_ERROR) {
   5716             waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
   5717             rc = apiResult.status;
   5718         }
   5719         unlockAPI();
   5720     } else if (true == m_bIntRawEvtPending) {
   5721         //Attempting to take RAW snapshot
   5722         (void)JpegMemOpt;
   5723         stopPreview();
   5724 
   5725         //getting the existing raw format type
   5726         property_get("persist.camera.raw.format", raw_format, "17");
   5727         //setting it to a default know value for this task
   5728         property_set("persist.camera.raw.format", "18");
   5729 
   5730         rc = addChannel(QCAMERA_CH_TYPE_RAW);
   5731         if (rc == NO_ERROR) {
   5732             // start postprocessor
   5733             if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   5734                 LOGE("Init PProc Deferred work failed");
   5735                 return UNKNOWN_ERROR;
   5736             }
   5737             rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
   5738             if (rc != NO_ERROR) {
   5739                 LOGE("cannot start postprocessor");
   5740                 delChannel(QCAMERA_CH_TYPE_RAW);
   5741                 return rc;
   5742             }
   5743 
   5744             rc = startChannel(QCAMERA_CH_TYPE_RAW);
   5745             if (rc != NO_ERROR) {
   5746                 LOGE("cannot start raw channel");
   5747                 m_postprocessor.stop();
   5748                 delChannel(QCAMERA_CH_TYPE_RAW);
   5749                 return rc;
   5750             }
   5751         } else {
   5752             LOGE("cannot add raw channel");
   5753             return rc;
   5754         }
   5755     }
   5756 
   5757     return rc;
   5758 }
   5759 
   5760 /*===========================================================================
   5761  * FUNCTION   : clearIntPendingEvents
   5762  *
   5763  * DESCRIPTION: clear internal pending events pertaining to backend
   5764  *                        snapshot requests
   5765  *
   5766  * PARAMETERS : none
   5767  *
   5768  * RETURN     : int32_t type of status
   5769  *              NO_ERROR  -- success
   5770  *              none-zero failure code
   5771  *==========================================================================*/
   5772 void QCamera2HardwareInterface::clearIntPendingEvents()
   5773 {
   5774     int rc = NO_ERROR;
   5775 
   5776     if (true == m_bIntRawEvtPending) {
   5777         preparePreview();
   5778         startPreview();
   5779     }
   5780     if (true == m_bIntJpegEvtPending) {
   5781         if (false == mParameters.isZSLMode()) {
   5782             lockAPI();
   5783             rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
   5784             unlockAPI();
   5785         }
   5786     }
   5787 
   5788     pthread_mutex_lock(&m_int_lock);
   5789     if (true == m_bIntJpegEvtPending) {
   5790         m_bIntJpegEvtPending = false;
   5791     } else if (true == m_bIntRawEvtPending) {
   5792         m_bIntRawEvtPending = false;
   5793     }
   5794     pthread_mutex_unlock(&m_int_lock);
   5795     return;
   5796 }
   5797 
   5798 /*===========================================================================
   5799  * FUNCTION   : takeLiveSnapshot_internal
   5800  *
   5801  * DESCRIPTION: take live snapshot during recording
   5802  *
   5803  * PARAMETERS : none
   5804  *
   5805  * RETURN     : int32_t type of status
   5806  *              NO_ERROR  -- success
   5807  *              none-zero failure code
   5808  *==========================================================================*/
   5809 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
   5810 {
   5811     int rc = NO_ERROR;
   5812 
   5813     QCameraChannel *pChannel = NULL;
   5814     QCameraChannel *pPreviewChannel = NULL;
   5815     QCameraStream  *pPreviewStream = NULL;
   5816     QCameraStream  *pStream = NULL;
   5817 
   5818     //Set rotation value from user settings as Jpeg rotation
   5819     //to configure back-end modules.
   5820     mParameters.setJpegRotation(mParameters.getRotation());
   5821 
   5822     // Configure advanced capture
   5823     rc = configureAdvancedCapture();
   5824     if (rc != NO_ERROR) {
   5825         LOGE("Unsupported capture call");
   5826         goto end;
   5827     }
   5828 
   5829     if (isLowPowerMode()) {
   5830         pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
   5831     } else {
   5832         pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   5833     }
   5834 
   5835     if (NULL == pChannel) {
   5836         LOGE("Snapshot/Video channel not initialized");
   5837         rc = NO_INIT;
   5838         goto end;
   5839     }
   5840 
   5841     // Check if all preview buffers are mapped before creating
   5842     // a jpeg session as preview stream buffers are queried during the same
   5843     pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   5844     if (pPreviewChannel != NULL) {
   5845         uint32_t numStreams = pPreviewChannel->getNumOfStreams();
   5846 
   5847         for (uint8_t i = 0 ; i < numStreams ; i++ ) {
   5848             pStream = pPreviewChannel->getStreamByIndex(i);
   5849             if (!pStream)
   5850                 continue;
   5851             if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
   5852                 pPreviewStream = pStream;
   5853                 break;
   5854             }
   5855         }
   5856 
   5857         if (pPreviewStream != NULL) {
   5858             Mutex::Autolock l(mMapLock);
   5859             QCameraMemory *pMemory = pStream->getStreamBufs();
   5860             if (!pMemory) {
   5861                 LOGE("Error!! pMemory is NULL");
   5862                 return -ENOMEM;
   5863             }
   5864 
   5865             uint8_t waitCnt = 2;
   5866             while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
   5867                 LOGL(" Waiting for preview buffers to be mapped");
   5868                 mMapCond.waitRelative(
   5869                         mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
   5870                 LOGL("Wait completed!!");
   5871                 waitCnt--;
   5872             }
   5873             // If all buffers are not mapped after retries, assert
   5874             assert(pMemory->checkIfAllBuffersMapped());
   5875         } else {
   5876             assert(pPreviewStream);
   5877         }
   5878     }
   5879 
   5880     DeferWorkArgs args;
   5881     memset(&args, 0, sizeof(DeferWorkArgs));
   5882 
   5883     args.pprocArgs = pChannel;
   5884 
   5885     // No need to wait for mInitPProcJob here, because it was
   5886     // queued in startPreview, and will definitely be processed before
   5887     // mReprocJob can begin.
   5888     mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   5889             args);
   5890     if (mReprocJob == 0) {
   5891         LOGE("Failed to queue CMD_DEF_PPROC_START");
   5892         rc = -ENOMEM;
   5893         goto end;
   5894     }
   5895 
   5896     // Create JPEG session
   5897     mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   5898             args);
   5899     if (mJpegJob == 0) {
   5900         LOGE("Failed to queue CREATE_JPEG_SESSION");
   5901         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5902             LOGE("Reprocess Deferred work was failed");
   5903         }
   5904         m_postprocessor.stop();
   5905         rc = -ENOMEM;
   5906         goto end;
   5907     }
   5908 
   5909     if (isLowPowerMode()) {
   5910         mm_camera_req_buf_t buf;
   5911         memset(&buf, 0x0, sizeof(buf));
   5912         buf.type = MM_CAMERA_REQ_SUPER_BUF;
   5913         buf.num_buf_requested = 1;
   5914         rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
   5915         goto end;
   5916     }
   5917 
   5918     //Disable reprocess for 4K liveshot case
   5919     if (!mParameters.is4k2kVideoResolution()) {
   5920         rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
   5921         if (rc != NO_ERROR) {
   5922             LOGE("online rotation failed");
   5923             if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5924                 LOGE("Reprocess Deferred work was failed");
   5925             }
   5926             if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   5927                 LOGE("Jpeg Deferred work was failed");
   5928             }
   5929             m_postprocessor.stop();
   5930             return rc;
   5931         }
   5932     }
   5933 
   5934     if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
   5935         QCameraStream *pStream = NULL;
   5936         for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
   5937             pStream = pChannel->getStreamByIndex(i);
   5938             if ((NULL != pStream) &&
   5939                     (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
   5940                 break;
   5941             }
   5942         }
   5943         if (pStream != NULL) {
   5944             LOGD("REQUEST_FRAMES event for TNR snapshot");
   5945             cam_stream_parm_buffer_t param;
   5946             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
   5947             param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
   5948             param.frameRequest.enableStream = 1;
   5949             rc = pStream->setParameter(param);
   5950             if (rc != NO_ERROR) {
   5951                 LOGE("Stream Event REQUEST_FRAMES failed");
   5952             }
   5953             goto end;
   5954         }
   5955     }
   5956 
   5957     // start snapshot channel
   5958     if ((rc == NO_ERROR) && (NULL != pChannel)) {
   5959         // Do not link metadata stream for 4K2k resolution
   5960         // as CPP processing would be done on snapshot stream and not
   5961         // reprocess stream
   5962         if (!mParameters.is4k2kVideoResolution()) {
   5963             // Find and try to link a metadata stream from preview channel
   5964             QCameraChannel *pMetaChannel = NULL;
   5965             QCameraStream *pMetaStream = NULL;
   5966             QCameraStream *pPreviewStream = NULL;
   5967 
   5968             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   5969                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   5970                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
   5971                 QCameraStream *pStream = NULL;
   5972                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   5973                     pStream = pMetaChannel->getStreamByIndex(i);
   5974                     if (NULL != pStream) {
   5975                         if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
   5976                             pMetaStream = pStream;
   5977                         } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType())
   5978                                 && (!mParameters.isHfrMode())
   5979                                 && (mParameters.isLinkPreviewForLiveShot())) {
   5980                             // Do not link preview stream for
   5981                             // 1)HFR live snapshot,Thumbnail will not be derived from
   5982                             //   preview for HFR live snapshot.
   5983                             // 2)persist.camera.linkpreview is 0
   5984                             pPreviewStream = pStream;
   5985                         }
   5986                     }
   5987                 }
   5988             }
   5989 
   5990             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   5991                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   5992                 if (NO_ERROR != rc) {
   5993                     LOGE("Metadata stream link failed %d", rc);
   5994                 }
   5995             }
   5996             if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
   5997                 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
   5998                 if (NO_ERROR != rc) {
   5999                     LOGE("Preview stream link failed %d", rc);
   6000                 }
   6001             }
   6002         }
   6003         rc = pChannel->start();
   6004     }
   6005 
   6006 end:
   6007     if (rc != NO_ERROR) {
   6008         rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
   6009         rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
   6010     }
   6011     return rc;
   6012 }
   6013 
   6014 /*===========================================================================
   6015  * FUNCTION   : cancelLiveSnapshot
   6016  *
   6017  * DESCRIPTION: cancel current live snapshot request
   6018  *
   6019  * PARAMETERS : none
   6020  *
   6021  * RETURN     : int32_t type of status
   6022  *              NO_ERROR  -- success
   6023  *              none-zero failure code
   6024  *==========================================================================*/
   6025 int QCamera2HardwareInterface::cancelLiveSnapshot()
   6026 {
   6027     int rc = NO_ERROR;
   6028     if (mLiveSnapshotThread != 0) {
   6029         pthread_join(mLiveSnapshotThread,NULL);
   6030         mLiveSnapshotThread = 0;
   6031     }
   6032     bLiveSnapshot = false;
   6033     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
   6034     if (!rc) {
   6035         pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap");
   6036     }
   6037     return rc;
   6038 }
   6039 
   6040 /*===========================================================================
   6041  * FUNCTION   : cancelLiveSnapshot_internal
   6042  *
   6043  * DESCRIPTION: cancel live snapshot during recording
   6044  *
   6045  * PARAMETERS : none
   6046  *
   6047  * RETURN     : int32_t type of status
   6048  *              NO_ERROR  -- success
   6049  *              none-zero failure code
   6050  *==========================================================================*/
   6051 int QCamera2HardwareInterface::cancelLiveSnapshot_internal() {
   6052     int rc = NO_ERROR;
   6053 
   6054     unconfigureAdvancedCapture();
   6055     LOGH("Enable display frames again");
   6056     setDisplaySkip(FALSE);
   6057 
   6058     //wait for deferred (reprocess and jpeg) threads to finish
   6059     waitDeferredWork(mReprocJob);
   6060     waitDeferredWork(mJpegJob);
   6061     //stop post processor
   6062     m_postprocessor.stop();
   6063 
   6064     // stop snapshot channel
   6065     if (!mParameters.isTNRSnapshotEnabled()) {
   6066         rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   6067     } else {
   6068         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   6069         if (NULL != pChannel) {
   6070             QCameraStream *pStream = NULL;
   6071             for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
   6072                 pStream = pChannel->getStreamByIndex(i);
   6073                 if ((NULL != pStream) &&
   6074                         (CAM_STREAM_TYPE_SNAPSHOT ==
   6075                         pStream->getMyType())) {
   6076                     break;
   6077                 }
   6078             }
   6079             if (pStream != NULL) {
   6080                 LOGD("REQUEST_FRAMES event for TNR snapshot");
   6081                 cam_stream_parm_buffer_t param;
   6082                 memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
   6083                 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
   6084                 param.frameRequest.enableStream = 0;
   6085                 rc = pStream->setParameter(param);
   6086                 if (rc != NO_ERROR) {
   6087                     LOGE("Stream Event REQUEST_FRAMES failed");
   6088                 }
   6089             }
   6090         }
   6091     }
   6092 
   6093     return rc;
   6094 }
   6095 
   6096 /*===========================================================================
   6097  * FUNCTION   : putParameters
   6098  *
   6099  * DESCRIPTION: put parameters string impl
   6100  *
   6101  * PARAMETERS :
   6102  *   @parms   : parameters string to be released
   6103  *
   6104  * RETURN     : int32_t type of status
   6105  *              NO_ERROR  -- success
   6106  *              none-zero failure code
   6107  *==========================================================================*/
   6108 int QCamera2HardwareInterface::putParameters(char *parms)
   6109 {
   6110     free(parms);
   6111     return NO_ERROR;
   6112 }
   6113 
   6114 /*===========================================================================
   6115  * FUNCTION   : sendCommand
   6116  *
   6117  * DESCRIPTION: send command impl
   6118  *
   6119  * PARAMETERS :
   6120  *   @command : command to be executed
   6121  *   @arg1    : optional argument 1
   6122  *   @arg2    : optional argument 2
   6123  *
   6124  * RETURN     : int32_t type of status
   6125  *              NO_ERROR  -- success
   6126  *              none-zero failure code
   6127  *==========================================================================*/
   6128 int QCamera2HardwareInterface::sendCommand(int32_t command,
   6129         __unused int32_t &arg1, __unused int32_t &arg2)
   6130 {
   6131     int rc = NO_ERROR;
   6132 
   6133     switch (command) {
   6134 #ifndef VANILLA_HAL
   6135     case CAMERA_CMD_LONGSHOT_ON:
   6136         arg1 = arg2 = 0;
   6137         // Longshot can only be enabled when image capture
   6138         // is not active.
   6139         if ( !m_stateMachine.isCaptureRunning() ) {
   6140             LOGI("Longshot Enabled");
   6141             mLongshotEnabled = true;
   6142             rc = mParameters.setLongshotEnable(mLongshotEnabled);
   6143 
   6144             // Due to recent buffer count optimizations
   6145             // ZSL might run with considerably less buffers
   6146             // when not in longshot mode. Preview needs to
   6147             // restart in this case.
   6148             if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
   6149                 QCameraChannel *pChannel = NULL;
   6150                 QCameraStream *pSnapStream = NULL;
   6151                 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   6152                 if (NULL != pChannel) {
   6153                     QCameraStream *pStream = NULL;
   6154                     for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
   6155                         pStream = pChannel->getStreamByIndex(i);
   6156                         if (pStream != NULL) {
   6157                             if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
   6158                                 pSnapStream = pStream;
   6159                                 break;
   6160                             }
   6161                         }
   6162                     }
   6163                     if (NULL != pSnapStream) {
   6164                         uint8_t required = 0;
   6165                         required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
   6166                         if (pSnapStream->getBufferCount() < required) {
   6167                             // We restart here, to reset the FPS and no
   6168                             // of buffers as per the requirement of longshot usecase.
   6169                             arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
   6170                             if (getRelatedCamSyncInfo()->sync_control ==
   6171                                     CAM_SYNC_RELATED_SENSORS_ON) {
   6172                                 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
   6173                             }
   6174                         }
   6175                     }
   6176                 }
   6177             }
   6178             //
   6179             mPrepSnapRun = false;
   6180             mCACDoneReceived = FALSE;
   6181         } else {
   6182             rc = NO_INIT;
   6183         }
   6184         break;
   6185     case CAMERA_CMD_LONGSHOT_OFF:
   6186         if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
   6187             cancelPicture();
   6188             processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
   6189             QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   6190             if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
   6191                 mCameraHandle->ops->stop_zsl_snapshot(
   6192                         mCameraHandle->camera_handle,
   6193                         pZSLChannel->getMyHandle());
   6194             }
   6195         }
   6196         mPrepSnapRun = false;
   6197         LOGI("Longshot Disabled");
   6198         mLongshotEnabled = false;
   6199         rc = mParameters.setLongshotEnable(mLongshotEnabled);
   6200         mCACDoneReceived = FALSE;
   6201         break;
   6202     case CAMERA_CMD_HISTOGRAM_ON:
   6203     case CAMERA_CMD_HISTOGRAM_OFF:
   6204         rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
   6205         LOGH("Histogram -> %s",
   6206               mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
   6207         break;
   6208 #endif
   6209     case CAMERA_CMD_START_FACE_DETECTION:
   6210     case CAMERA_CMD_STOP_FACE_DETECTION:
   6211         mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
   6212         rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
   6213         LOGH("FaceDetection -> %s",
   6214               mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
   6215         break;
   6216 #ifndef VANILLA_HAL
   6217     case CAMERA_CMD_HISTOGRAM_SEND_DATA:
   6218 #endif
   6219     default:
   6220         rc = NO_ERROR;
   6221         break;
   6222     }
   6223     return rc;
   6224 }
   6225 
   6226 /*===========================================================================
   6227  * FUNCTION   : registerFaceImage
   6228  *
   6229  * DESCRIPTION: register face image impl
   6230  *
   6231  * PARAMETERS :
   6232  *   @img_ptr : ptr to image buffer
   6233  *   @config  : ptr to config struct about input image info
   6234  *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
   6235  *
   6236  * RETURN     : int32_t type of status
   6237  *              NO_ERROR  -- success
   6238  *              none-zero failure code
   6239  *==========================================================================*/
   6240 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
   6241                                                  cam_pp_offline_src_config_t *config,
   6242                                                  int32_t &faceID)
   6243 {
   6244     int rc = NO_ERROR;
   6245     faceID = -1;
   6246 
   6247     if (img_ptr == NULL || config == NULL) {
   6248         LOGE("img_ptr or config is NULL");
   6249         return BAD_VALUE;
   6250     }
   6251 
   6252     // allocate ion memory for source image
   6253     QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   6254     if (imgBuf == NULL) {
   6255         LOGE("Unable to new heap memory obj for image buf");
   6256         return NO_MEMORY;
   6257     }
   6258 
   6259     rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len);
   6260     if (rc < 0) {
   6261         LOGE("Unable to allocate heap memory for image buf");
   6262         delete imgBuf;
   6263         return NO_MEMORY;
   6264     }
   6265 
   6266     void *pBufPtr = imgBuf->getPtr(0);
   6267     if (pBufPtr == NULL) {
   6268         LOGE("image buf is NULL");
   6269         imgBuf->deallocate();
   6270         delete imgBuf;
   6271         return NO_MEMORY;
   6272     }
   6273     memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
   6274     //Do cache ops before sending for reprocess
   6275     imgBuf->cacheOps(0, ION_IOC_CLEAN_INV_CACHES);
   6276 
   6277     cam_pp_feature_config_t pp_feature;
   6278     memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
   6279     pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
   6280     QCameraReprocessChannel *pChannel =
   6281         addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
   6282 
   6283     if (pChannel == NULL) {
   6284         LOGE("fail to add offline reprocess channel");
   6285         imgBuf->deallocate();
   6286         delete imgBuf;
   6287         return UNKNOWN_ERROR;
   6288     }
   6289 
   6290     rc = pChannel->start();
   6291     if (rc != NO_ERROR) {
   6292         LOGE("Cannot start reprocess channel");
   6293         imgBuf->deallocate();
   6294         delete imgBuf;
   6295         delete pChannel;
   6296         return rc;
   6297     }
   6298 
   6299     ssize_t bufSize = imgBuf->getSize(0);
   6300     if (BAD_INDEX != bufSize) {
   6301         rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0),
   6302                 (size_t)bufSize, faceID);
   6303     } else {
   6304         LOGE("Failed to retrieve buffer size (bad index)");
   6305         return UNKNOWN_ERROR;
   6306     }
   6307 
   6308     // done with register face image, free imgbuf and delete reprocess channel
   6309     imgBuf->deallocate();
   6310     delete imgBuf;
   6311     imgBuf = NULL;
   6312     pChannel->stop();
   6313     delete pChannel;
   6314     pChannel = NULL;
   6315 
   6316     return rc;
   6317 }
   6318 
   6319 /*===========================================================================
   6320  * FUNCTION   : release
   6321  *
   6322  * DESCRIPTION: release camera resource impl
   6323  *
   6324  * PARAMETERS : none
   6325  *
   6326  * RETURN     : int32_t type of status
   6327  *              NO_ERROR  -- success
   6328  *              none-zero failure code
   6329  *==========================================================================*/
   6330 int QCamera2HardwareInterface::release()
   6331 {
   6332     // stop and delete all channels
   6333     for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
   6334         if (m_channels[i] != NULL) {
   6335             stopChannel((qcamera_ch_type_enum_t)i);
   6336             delChannel((qcamera_ch_type_enum_t)i);
   6337         }
   6338     }
   6339 
   6340     return NO_ERROR;
   6341 }
   6342 
   6343 /*===========================================================================
   6344  * FUNCTION   : dump
   6345  *
   6346  * DESCRIPTION: camera status dump impl
   6347  *
   6348  * PARAMETERS :
   6349  *   @fd      : fd for the buffer to be dumped with camera status
   6350  *
   6351  * RETURN     : int32_t type of status
   6352  *              NO_ERROR  -- success
   6353  *              none-zero failure code
   6354  *==========================================================================*/
   6355 int QCamera2HardwareInterface::dump(int fd)
   6356 {
   6357     dprintf(fd, "\n Camera HAL information Begin \n");
   6358     dprintf(fd, "Camera ID: %d \n", mCameraId);
   6359     dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
   6360     dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
   6361     dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
   6362     dprintf(fd, "\n Camera HAL information End \n");
   6363 
   6364     /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
   6365        debug level property */
   6366     mParameters.updateDebugLevel();
   6367     return NO_ERROR;
   6368 }
   6369 
   6370 /*===========================================================================
   6371  * FUNCTION   : processAPI
   6372  *
   6373  * DESCRIPTION: process API calls from upper layer
   6374  *
   6375  * PARAMETERS :
   6376  *   @api         : API to be processed
   6377  *   @api_payload : ptr to API payload if any
   6378  *
   6379  * RETURN     : int32_t type of status
   6380  *              NO_ERROR  -- success
   6381  *              none-zero failure code
   6382  *==========================================================================*/
   6383 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
   6384 {
   6385     int ret = DEAD_OBJECT;
   6386 
   6387     if (m_smThreadActive) {
   6388         ret = m_stateMachine.procAPI(api, api_payload);
   6389     }
   6390 
   6391     return ret;
   6392 }
   6393 
   6394 /*===========================================================================
   6395  * FUNCTION   : processEvt
   6396  *
   6397  * DESCRIPTION: process Evt from backend via mm-camera-interface
   6398  *
   6399  * PARAMETERS :
   6400  *   @evt         : event type to be processed
   6401  *   @evt_payload : ptr to event payload if any
   6402  *
   6403  * RETURN     : int32_t type of status
   6404  *              NO_ERROR  -- success
   6405  *              none-zero failure code
   6406  *==========================================================================*/
   6407 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
   6408 {
   6409     return m_stateMachine.procEvt(evt, evt_payload);
   6410 }
   6411 
   6412 /*===========================================================================
   6413  * FUNCTION   : processSyncEvt
   6414  *
   6415  * DESCRIPTION: process synchronous Evt from backend
   6416  *
   6417  * PARAMETERS :
   6418  *   @evt         : event type to be processed
   6419  *   @evt_payload : ptr to event payload if any
   6420  *
   6421  * RETURN     : int32_t type of status
   6422  *              NO_ERROR  -- success
   6423  *              none-zero failure code
   6424  *==========================================================================*/
   6425 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
   6426 {
   6427     int rc = NO_ERROR;
   6428 
   6429     pthread_mutex_lock(&m_evtLock);
   6430     rc =  processEvt(evt, evt_payload);
   6431     if (rc == NO_ERROR) {
   6432         memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
   6433         while (m_evtResult.request_api != evt) {
   6434             pthread_cond_wait(&m_evtCond, &m_evtLock);
   6435         }
   6436         rc =  m_evtResult.status;
   6437     }
   6438     pthread_mutex_unlock(&m_evtLock);
   6439 
   6440     return rc;
   6441 }
   6442 
   6443 /*===========================================================================
   6444  * FUNCTION   : evtHandle
   6445  *
   6446  * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
   6447  *
   6448  * PARAMETERS :
   6449  *   @camera_handle : event type to be processed
   6450  *   @evt           : ptr to event
   6451  *   @user_data     : user data ptr
   6452  *
   6453  * RETURN     : none
   6454  *==========================================================================*/
   6455 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
   6456                                           mm_camera_event_t *evt,
   6457                                           void *user_data)
   6458 {
   6459     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
   6460     if (obj && evt) {
   6461         mm_camera_event_t *payload =
   6462             (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
   6463         if (NULL != payload) {
   6464             *payload = *evt;
   6465             //peek into the event, if this is an eztune event from server,
   6466             //then we don't need to post it to the SM Qs, we shud directly
   6467             //spawn a thread and get the job done (jpeg or raw snapshot)
   6468             switch (payload->server_event_type) {
   6469                 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
   6470                     //Received JPEG trigger from eztune
   6471                     if (false == obj->m_bIntJpegEvtPending) {
   6472                         pthread_mutex_lock(&obj->m_int_lock);
   6473                         obj->m_bIntJpegEvtPending = true;
   6474                         pthread_mutex_unlock(&obj->m_int_lock);
   6475                         obj->takePictureInternal();
   6476                     }
   6477                     free(payload);
   6478                     break;
   6479                 case CAM_EVENT_TYPE_INT_TAKE_RAW:
   6480                     //Received RAW trigger from eztune
   6481                     if (false == obj->m_bIntRawEvtPending) {
   6482                         pthread_mutex_lock(&obj->m_int_lock);
   6483                         obj->m_bIntRawEvtPending = true;
   6484                         pthread_mutex_unlock(&obj->m_int_lock);
   6485                         obj->takePictureInternal();
   6486                     }
   6487                     free(payload);
   6488                     break;
   6489                 case CAM_EVENT_TYPE_DAEMON_DIED:
   6490                     {
   6491                         Mutex::Autolock l(obj->mDefLock);
   6492                         obj->mDefCond.broadcast();
   6493                         LOGH("broadcast mDefCond signal\n");
   6494                     }
   6495                 default:
   6496                     obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
   6497                     break;
   6498             }
   6499         }
   6500     } else {
   6501         LOGE("NULL user_data");
   6502     }
   6503 }
   6504 
   6505 /*===========================================================================
   6506  * FUNCTION   : jpegEvtHandle
   6507  *
   6508  * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
   6509  *
   6510  * PARAMETERS :
   6511  *   @status    : status of jpeg job
   6512  *   @client_hdl: jpeg client handle
   6513  *   @jobId     : jpeg job Id
   6514  *   @p_ouput   : ptr to jpeg output result struct
   6515  *   @userdata  : user data ptr
   6516  *
   6517  * RETURN     : none
   6518  *==========================================================================*/
   6519 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
   6520                                               uint32_t /*client_hdl*/,
   6521                                               uint32_t jobId,
   6522                                               mm_jpeg_output_t *p_output,
   6523                                               void *userdata)
   6524 {
   6525     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
   6526     if (obj) {
   6527         qcamera_jpeg_evt_payload_t *payload =
   6528             (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
   6529         if (NULL != payload) {
   6530             memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
   6531             payload->status = status;
   6532             payload->jobId = jobId;
   6533             if (p_output != NULL) {
   6534                 payload->out_data = *p_output;
   6535             }
   6536             obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
   6537         }
   6538     } else {
   6539         LOGE("NULL user_data");
   6540     }
   6541 }
   6542 
   6543 /*===========================================================================
   6544  * FUNCTION   : thermalEvtHandle
   6545  *
   6546  * DESCRIPTION: routine to handle thermal event notification
   6547  *
   6548  * PARAMETERS :
   6549  *   @level      : thermal level
   6550  *   @userdata   : userdata passed in during registration
   6551  *   @data       : opaque data from thermal client
   6552  *
   6553  * RETURN     : int32_t type of status
   6554  *              NO_ERROR  -- success
   6555  *              none-zero failure code
   6556  *==========================================================================*/
   6557 int QCamera2HardwareInterface::thermalEvtHandle(
   6558         qcamera_thermal_level_enum_t *level, void *userdata, void *data)
   6559 {
   6560     if (!mCameraOpened) {
   6561         LOGH("Camera is not opened, no need to handle thermal evt");
   6562         return NO_ERROR;
   6563     }
   6564 
   6565     // Make sure thermal events are logged
   6566     LOGH("level = %d, userdata = %p, data = %p",
   6567          *level, userdata, data);
   6568     //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
   6569     // becomes an aync call. This also means we can only pass payload
   6570     // by value, not by address.
   6571     return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
   6572 }
   6573 
   6574 /*===========================================================================
   6575  * FUNCTION   : sendEvtNotify
   6576  *
   6577  * DESCRIPTION: send event notify to notify thread
   6578  *
   6579  * PARAMETERS :
   6580  *   @msg_type: msg type to be sent
   6581  *   @ext1    : optional extension1
   6582  *   @ext2    : optional extension2
   6583  *
   6584  * RETURN     : int32_t type of status
   6585  *              NO_ERROR  -- success
   6586  *              none-zero failure code
   6587  *==========================================================================*/
   6588 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
   6589                                                  int32_t ext1,
   6590                                                  int32_t ext2)
   6591 {
   6592     qcamera_callback_argm_t cbArg;
   6593     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   6594     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
   6595     cbArg.msg_type = msg_type;
   6596     cbArg.ext1 = ext1;
   6597     cbArg.ext2 = ext2;
   6598     return m_cbNotifier.notifyCallback(cbArg);
   6599 }
   6600 
   6601 /*===========================================================================
   6602  * FUNCTION   : processAEInfo
   6603  *
   6604  * DESCRIPTION: process AE updates
   6605  *
   6606  * PARAMETERS :
   6607  *   @ae_params: current AE parameters
   6608  *
   6609  * RETURN     : None
   6610  *==========================================================================*/
   6611 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
   6612 {
   6613     mParameters.updateAEInfo(ae_params);
   6614     if (mParameters.isInstantAECEnabled()) {
   6615         // Reset Instant AEC info only if instant aec enabled.
   6616         bool bResetInstantAec = false;
   6617         if (ae_params.settled) {
   6618             // If AEC settled, reset instant AEC
   6619             bResetInstantAec = true;
   6620         } else if ((mParameters.isInstantCaptureEnabled()) &&
   6621                 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
   6622             // if AEC not settled, and instant capture enabled,
   6623             // reset instant AEC only when frame count is
   6624             // more or equal to AEC frame bound value.
   6625             bResetInstantAec = true;
   6626         } else if ((mParameters.isInstantAECEnabled()) &&
   6627                 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
   6628             // if AEC not settled, and only instant AEC enabled,
   6629             // reset instant AEC only when frame count is
   6630             // more or equal to AEC skip display frame bound value.
   6631             bResetInstantAec = true;
   6632         }
   6633 
   6634         if (bResetInstantAec) {
   6635             LOGD("setting instant AEC to false");
   6636             mParameters.setInstantAEC(false, true);
   6637             mInstantAecFrameCount = 0;
   6638         }
   6639     }
   6640     return NO_ERROR;
   6641 }
   6642 
   6643 /*===========================================================================
   6644  * FUNCTION   : processFocusPositionInfo
   6645  *
   6646  * DESCRIPTION: process AF updates
   6647  *
   6648  * PARAMETERS :
   6649  *   @cur_pos_info: current lens position
   6650  *
   6651  * RETURN     : None
   6652  *==========================================================================*/
   6653 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
   6654 {
   6655     mParameters.updateCurrentFocusPosition(cur_pos_info);
   6656     return NO_ERROR;
   6657 }
   6658 
   6659 /*===========================================================================
   6660  * FUNCTION   : processAutoFocusEvent
   6661  *
   6662  * DESCRIPTION: process auto focus event
   6663  *
   6664  * PARAMETERS :
   6665  *   @focus_data: struct containing auto focus result info
   6666  *
   6667  * RETURN     : int32_t type of status
   6668  *              NO_ERROR  -- success
   6669  *              none-zero failure code
   6670  *==========================================================================*/
   6671 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
   6672 {
   6673     int32_t ret = NO_ERROR;
   6674     LOGH("E");
   6675 
   6676     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
   6677         // Ignore focus updates
   6678         LOGH("X Secondary Camera, no need to process!! ");
   6679         return ret;
   6680     }
   6681     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   6682     LOGH("[AF_DBG]  focusMode=%d, focusState=%d isDepth=%d",
   6683              focusMode, focus_data.focus_state, focus_data.isDepth);
   6684 
   6685     switch (focusMode) {
   6686     case CAM_FOCUS_MODE_AUTO:
   6687     case CAM_FOCUS_MODE_MACRO:
   6688         // ignore AF event if AF was already cancelled meanwhile
   6689         if (!mActiveAF) {
   6690             break;
   6691         }
   6692         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
   6693         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
   6694                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6695             ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
   6696             mActiveAF = false; // reset the mActiveAF in this special case
   6697             break;
   6698         }
   6699 
   6700         //while transitioning from CAF->Auto/Macro, we might receive CAF related
   6701         //events (PASSIVE_*) due to timing. Ignore such events if any.
   6702         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
   6703                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6704                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
   6705             break;
   6706         }
   6707 
   6708         //This is just an intermediate update to HAL indicating focus is in progress. No need
   6709         //to send this event to app. Same applies to INACTIVE state as well.
   6710         if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
   6711                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6712             break;
   6713         }
   6714         // update focus distance
   6715         mParameters.updateFocusDistances(&focus_data.focus_dist);
   6716 
   6717         //flush any old snapshot frames in ZSL Q which are not focused.
   6718         if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
   6719             QCameraPicChannel *pZSLChannel =
   6720                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   6721             if (NULL != pZSLChannel) {
   6722                 //flush the zsl-buffer
   6723                 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
   6724                 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
   6725                 pZSLChannel->flushSuperbuffer(flush_frame_idx);
   6726             }
   6727         }
   6728 
   6729         //send event to app finally
   6730         LOGI("Send AF DOne event to app");
   6731         ret = sendEvtNotify(CAMERA_MSG_FOCUS,
   6732                             (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
   6733         break;
   6734     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   6735     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   6736 
   6737         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
   6738         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
   6739                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6740             ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
   6741             mActiveAF = false; // reset the mActiveAF in this special case
   6742             break;
   6743         }
   6744 
   6745         //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
   6746         //process/wait for only ACTIVE_* events.
   6747         if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6748                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
   6749                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
   6750             break;
   6751         }
   6752 
   6753         if (!bDepthAFCallbacks && focus_data.isDepth &&
   6754                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) {
   6755             LOGD("Skip sending scan state to app, if depth focus");
   6756             break;
   6757         }
   6758 
   6759         //These are the AF states for which we need to send notification to app in CAF mode.
   6760         //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
   6761         //AF is triggered while in CAF mode)
   6762         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6763                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
   6764                 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
   6765                 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
   6766 
   6767             // update focus distance
   6768             mParameters.updateFocusDistances(&focus_data.focus_dist);
   6769 
   6770             if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
   6771                 QCameraPicChannel *pZSLChannel =
   6772                         (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   6773                 if (NULL != pZSLChannel) {
   6774                     //flush the zsl-buffer
   6775                     uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
   6776                     LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
   6777                     pZSLChannel->flushSuperbuffer(flush_frame_idx);
   6778                 }
   6779             }
   6780 
   6781             if (mActiveAF) {
   6782                 LOGI("Send AF Done event to app");
   6783             }
   6784             ret = sendEvtNotify(CAMERA_MSG_FOCUS,
   6785                     ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6786                     (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
   6787         }
   6788         ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
   6789                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
   6790         break;
   6791     case CAM_FOCUS_MODE_INFINITY:
   6792     case CAM_FOCUS_MODE_FIXED:
   6793     case CAM_FOCUS_MODE_EDOF:
   6794     default:
   6795         LOGH("no ops for autofocus event in focusmode %d", focusMode);
   6796         break;
   6797     }
   6798 
   6799     //Reset mActiveAF once we receive focus done event
   6800     if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
   6801             (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
   6802         mActiveAF = false;
   6803     }
   6804 
   6805     LOGH("X");
   6806     return ret;
   6807 }
   6808 
   6809 /*===========================================================================
   6810  * FUNCTION   : processZoomEvent
   6811  *
   6812  * DESCRIPTION: process zoom event
   6813  *
   6814  * PARAMETERS :
   6815  *   @crop_info : crop info as a result of zoom operation
   6816  *
   6817  * RETURN     : int32_t type of status
   6818  *              NO_ERROR  -- success
   6819  *              none-zero failure code
   6820  *==========================================================================*/
   6821 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
   6822 {
   6823     int32_t ret = NO_ERROR;
   6824 
   6825     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   6826         if (m_channels[i] != NULL) {
   6827             ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
   6828         }
   6829     }
   6830     return ret;
   6831 }
   6832 
   6833 /*===========================================================================
   6834  * FUNCTION   : processZSLCaptureDone
   6835  *
   6836  * DESCRIPTION: process ZSL capture done events
   6837  *
   6838  * PARAMETERS : None
   6839  *
   6840  * RETURN     : int32_t type of status
   6841  *              NO_ERROR  -- success
   6842  *              none-zero failure code
   6843  *==========================================================================*/
   6844 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
   6845 {
   6846     int rc = NO_ERROR;
   6847 
   6848     if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
   6849         rc = unconfigureAdvancedCapture();
   6850     }
   6851 
   6852     return rc;
   6853 }
   6854 
   6855 /*===========================================================================
   6856  * FUNCTION   : processRetroAECUnlock
   6857  *
   6858  * DESCRIPTION: process retro burst AEC unlock events
   6859  *
   6860  * PARAMETERS : None
   6861  *
   6862  * RETURN     : int32_t type of status
   6863  *              NO_ERROR  -- success
   6864  *              none-zero failure code
   6865  *==========================================================================*/
   6866 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
   6867 {
   6868     int rc = NO_ERROR;
   6869 
   6870     LOGH("LED assisted AF Release AEC Lock");
   6871     rc = mParameters.setAecLock("false");
   6872     if (NO_ERROR != rc) {
   6873         LOGE("Error setting AEC lock");
   6874         return rc;
   6875     }
   6876 
   6877     rc = mParameters.commitParameters();
   6878     if (NO_ERROR != rc) {
   6879         LOGE("Error during camera parameter commit");
   6880     } else {
   6881         m_bLedAfAecLock = FALSE;
   6882     }
   6883 
   6884     return rc;
   6885 }
   6886 
   6887 /*===========================================================================
   6888  * FUNCTION   : processHDRData
   6889  *
   6890  * DESCRIPTION: process HDR scene events
   6891  *
   6892  * PARAMETERS :
   6893  *   @hdr_scene : HDR scene event data
   6894  *
   6895  * RETURN     : int32_t type of status
   6896  *              NO_ERROR  -- success
   6897  *              none-zero failure code
   6898  *==========================================================================*/
   6899 int32_t QCamera2HardwareInterface::processHDRData(
   6900         __unused cam_asd_hdr_scene_data_t hdr_scene)
   6901 {
   6902     int rc = NO_ERROR;
   6903 
   6904 #ifndef VANILLA_HAL
   6905     if (hdr_scene.is_hdr_scene &&
   6906       (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
   6907       mParameters.isAutoHDREnabled()) {
   6908         m_HDRSceneEnabled = true;
   6909     } else {
   6910         m_HDRSceneEnabled = false;
   6911     }
   6912     mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
   6913 
   6914     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
   6915 
   6916         size_t data_len = sizeof(int);
   6917         size_t buffer_len = 1 *sizeof(int)       //meta type
   6918                           + 1 *sizeof(int)       //data len
   6919                           + 1 *sizeof(int);      //data
   6920         camera_memory_t *hdrBuffer = mGetMemory(-1,
   6921                                                  buffer_len,
   6922                                                  1,
   6923                                                  mCallbackCookie);
   6924         if ( NULL == hdrBuffer ) {
   6925             LOGE("Not enough memory for auto HDR data");
   6926             return NO_MEMORY;
   6927         }
   6928 
   6929         int *pHDRData = (int *)hdrBuffer->data;
   6930         if (pHDRData == NULL) {
   6931             LOGE("memory data ptr is NULL");
   6932             return UNKNOWN_ERROR;
   6933         }
   6934 
   6935         pHDRData[0] = CAMERA_META_DATA_HDR;
   6936         pHDRData[1] = (int)data_len;
   6937         pHDRData[2] = m_HDRSceneEnabled;
   6938 
   6939         qcamera_callback_argm_t cbArg;
   6940         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   6941         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   6942         cbArg.msg_type = CAMERA_MSG_META_DATA;
   6943         cbArg.data = hdrBuffer;
   6944         cbArg.user_data = hdrBuffer;
   6945         cbArg.cookie = this;
   6946         cbArg.release_cb = releaseCameraMemory;
   6947         rc = m_cbNotifier.notifyCallback(cbArg);
   6948         if (rc != NO_ERROR) {
   6949             LOGE("fail sending auto HDR notification");
   6950             hdrBuffer->release(hdrBuffer);
   6951         }
   6952     }
   6953 
   6954     LOGH("hdr_scene_data: processHDRData: %d %f",
   6955           hdr_scene.is_hdr_scene,
   6956           hdr_scene.hdr_confidence);
   6957 
   6958 #endif
   6959   return rc;
   6960 }
   6961 
   6962 /*===========================================================================
   6963  * FUNCTION   : processLEDCalibration
   6964  *
   6965  * DESCRIPTION: process LED calibration result
   6966  *
   6967  * PARAMETERS :
   6968  *   @value : Calibaration result
   6969  *
   6970  * RETURN     : int32_t type of status
   6971  *              NO_ERROR  -- success
   6972  *              none-zero failure code
   6973  *==========================================================================*/
   6974 int32_t QCamera2HardwareInterface::processLEDCalibration(int32_t value)
   6975 {
   6976     int32_t rc = NO_ERROR;
   6977 #ifndef VANILLA_HAL
   6978     if (mParameters.getDualLedCalibration()) {
   6979         LOGH("Dual LED calibration value = %d", value);
   6980         int32_t data_len = sizeof(value);
   6981         int32_t buffer_len = sizeof(int)       //meta type
   6982                 + sizeof(int)                  //data len
   6983                 + data_len;                    //data
   6984         camera_memory_t *buffer = mGetMemory(-1,
   6985                 buffer_len, 1, mCallbackCookie);
   6986         if ( NULL == buffer ) {
   6987             LOGE("Not enough memory for data");
   6988             return NO_MEMORY;
   6989         }
   6990 
   6991         int *pData = (int *)buffer->data;
   6992         if (pData == NULL) {
   6993             LOGE("memory data ptr is NULL");
   6994             buffer->release(buffer);
   6995             return UNKNOWN_ERROR;
   6996         }
   6997 
   6998         pData[0] = QCAMERA_METADATA_LED_CALIB;
   6999         pData[1] = (int)data_len;
   7000         pData[2] = value;
   7001 
   7002         qcamera_callback_argm_t cbArg;
   7003         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   7004         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   7005         cbArg.msg_type = CAMERA_MSG_META_DATA;
   7006         cbArg.data = buffer;
   7007         cbArg.user_data = buffer;
   7008         cbArg.cookie = this;
   7009         cbArg.release_cb = releaseCameraMemory;
   7010         int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   7011         if (rc != NO_ERROR) {
   7012             LOGE("fail sending notification");
   7013             buffer->release(buffer);
   7014         }
   7015     }
   7016 #else
   7017     (void)value;  // unused
   7018 #endif
   7019     return rc;
   7020 }
   7021 
   7022 
   7023 /*===========================================================================
   7024  * FUNCTION   : transAwbMetaToParams
   7025  *
   7026  * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
   7027  *
   7028  * PARAMETERS :
   7029  *   @awb_params : awb params from metadata callback
   7030  *
   7031  * RETURN     : int32_t type of status
   7032  *              NO_ERROR  -- success
   7033  *              none-zero failure code
   7034  *==========================================================================*/
   7035 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
   7036 {
   7037     mParameters.updateAWBParams(awb_params);
   7038     return NO_ERROR;
   7039 }
   7040 
   7041 /*===========================================================================
   7042  * FUNCTION   : processPrepSnapshotDone
   7043  *
   7044  * DESCRIPTION: process prep snapshot done event
   7045  *
   7046  * PARAMETERS :
   7047  *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
   7048  *                           i.e. whether need future frames for capture.
   7049  *
   7050  * RETURN     : int32_t type of status
   7051  *              NO_ERROR  -- success
   7052  *              none-zero failure code
   7053  *==========================================================================*/
   7054 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
   7055                         cam_prep_snapshot_state_t prep_snapshot_state)
   7056 {
   7057     int32_t ret = NO_ERROR;
   7058     LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
   7059             prep_snapshot_state);
   7060     if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
   7061         prep_snapshot_state == NEED_FUTURE_FRAME) {
   7062         LOGH("already handled in mm-camera-intf, no ops here");
   7063         if (isRetroPicture()) {
   7064             mParameters.setAecLock("true");
   7065             mParameters.commitParameters();
   7066             m_bLedAfAecLock = TRUE;
   7067         }
   7068     }
   7069     return ret;
   7070 }
   7071 
   7072 /*===========================================================================
   7073  * FUNCTION   : processASDUpdate
   7074  *
   7075  * DESCRIPTION: process ASD update event
   7076  *
   7077  * PARAMETERS :
   7078  *   @scene: selected scene mode
   7079  *
   7080  * RETURN     : int32_t type of status
   7081  *              NO_ERROR  -- success
   7082  *              none-zero failure code
   7083  *==========================================================================*/
   7084 int32_t QCamera2HardwareInterface::processASDUpdate(
   7085         __unused cam_asd_decision_t asd_decision)
   7086 {
   7087 #ifndef VANILLA_HAL
   7088     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
   7089         size_t data_len = sizeof(cam_auto_scene_t);
   7090         size_t buffer_len = 1 *sizeof(int)       //meta type
   7091                 + 1 *sizeof(int)       //data len
   7092                 + data_len;            //data
   7093         camera_memory_t *asdBuffer = mGetMemory(-1,
   7094                 buffer_len, 1, mCallbackCookie);
   7095         if ( NULL == asdBuffer ) {
   7096             LOGE("Not enough memory for histogram data");
   7097             return NO_MEMORY;
   7098         }
   7099 
   7100         int *pASDData = (int *)asdBuffer->data;
   7101         if (pASDData == NULL) {
   7102             LOGE("memory data ptr is NULL");
   7103             return UNKNOWN_ERROR;
   7104         }
   7105 
   7106         pASDData[0] = CAMERA_META_DATA_ASD;
   7107         pASDData[1] = (int)data_len;
   7108         pASDData[2] = asd_decision.detected_scene;
   7109 
   7110         qcamera_callback_argm_t cbArg;
   7111         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   7112         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   7113         cbArg.msg_type = CAMERA_MSG_META_DATA;
   7114         cbArg.data = asdBuffer;
   7115         cbArg.user_data = asdBuffer;
   7116         cbArg.cookie = this;
   7117         cbArg.release_cb = releaseCameraMemory;
   7118         int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   7119         if (rc != NO_ERROR) {
   7120             LOGE("fail sending notification");
   7121             asdBuffer->release(asdBuffer);
   7122         }
   7123     }
   7124 #endif
   7125     return NO_ERROR;
   7126 }
   7127 
   7128 /*===========================================================================
   7129  * FUNCTION   : processJpegNotify
   7130  *
   7131  * DESCRIPTION: process jpeg event
   7132  *
   7133  * PARAMETERS :
   7134  *   @jpeg_evt: ptr to jpeg event payload
   7135  *
   7136  * RETURN     : int32_t type of status
   7137  *              NO_ERROR  -- success
   7138  *              none-zero failure code
   7139  *==========================================================================*/
   7140 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
   7141 {
   7142     return m_postprocessor.processJpegEvt(jpeg_evt);
   7143 }
   7144 
   7145 
   7146 /*===========================================================================
   7147  * FUNCTION   : processDualCamFovControl
   7148  *
   7149  * DESCRIPTION: Based on the result collected from FOV control-
   7150  *              1. Switch the master camera if needed
   7151  *              2. Toggle the Low Power Mode for slave camera
   7152  *
   7153  * PARAMETERS : none
   7154  *
   7155  * RETURN     : none
   7156  *==========================================================================*/
   7157 void QCamera2HardwareInterface::processDualCamFovControl()
   7158 {
   7159    uint32_t activeCameras;
   7160    bool bundledSnapshot;
   7161    fov_control_result_t fovControlResult;
   7162    cam_sync_type_t camMasterSnapshot;
   7163 
   7164     if (!isDualCamera()) {
   7165         return;
   7166     }
   7167 
   7168     fovControlResult = m_pFovControl->getFovControlResult();
   7169 
   7170     if (fovControlResult.isValid) {
   7171         activeCameras = fovControlResult.activeCameras;
   7172         bundledSnapshot = fovControlResult.snapshotPostProcess;
   7173         camMasterSnapshot = fovControlResult.camMasterPreview;
   7174 
   7175         processCameraControl(activeCameras, bundledSnapshot);
   7176         switchCameraCb(fovControlResult.camMasterPreview);
   7177     }
   7178 }
   7179 
   7180 /*===========================================================================
   7181  * FUNCTION   : processCameraControl
   7182  *
   7183  * DESCRIPTION: Suspend and resume camera
   7184  *
   7185  * PARAMETERS :
   7186  *
   7187  * RETURN     : int32_t type of status
   7188  *              NO_ERROR  -- success
   7189  *              none-zero failure code
   7190  *==========================================================================*/
   7191 int32_t QCamera2HardwareInterface::processCameraControl(
   7192         uint32_t activeCameras,
   7193         bool     bundledSnapshot)
   7194 {
   7195     int32_t ret = NO_ERROR;
   7196 
   7197     //Update camera status to internal channel
   7198     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   7199         if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
   7200             ret = m_channels[i]->processCameraControl(activeCameras, bundledSnapshot);
   7201             if (ret != NO_ERROR) {
   7202                 LOGE("Channel Switch Failed");
   7203                 break;
   7204             }
   7205         }
   7206     }
   7207 
   7208     if ((activeCameras != mActiveCameras) ||
   7209             ((activeCameras == MM_CAMERA_DUAL_CAM) && (bundledSnapshot != mBundledSnapshot))) {
   7210 
   7211         if (activeCameras != mActiveCameras) {
   7212             //Set camera controls to parameter and back-end
   7213             ret = mParameters.setCameraControls(activeCameras);
   7214         }
   7215 
   7216         mParameters.setBundledSnapshot(bundledSnapshot);
   7217         mParameters.setNumOfSnapshot();
   7218 
   7219         LOGH("mActiveCameras = %d to %d, bundledSnapshot = %d to %d",
   7220                 mActiveCameras, activeCameras, mBundledSnapshot, bundledSnapshot);
   7221         mActiveCameras   = activeCameras;
   7222         mBundledSnapshot = bundledSnapshot;
   7223     }
   7224 
   7225     return ret;
   7226 }
   7227 
   7228 /*===========================================================================
   7229  * FUNCTION   : switchCameraCb
   7230  *
   7231  * DESCRIPTION: switch camera's in case of dual camera
   7232  *
   7233  * PARAMETERS :
   7234  * @camMaster : Master camera
   7235  *
   7236  * RETURN     : int32_t type of status
   7237  *              NO_ERROR  -- success
   7238  *              none-zero failure code
   7239  *==========================================================================*/
   7240 int32_t QCamera2HardwareInterface::switchCameraCb(uint32_t camMaster)
   7241 {
   7242     int32_t ret = NO_ERROR;
   7243 
   7244     if (mActiveCameras & camMaster) {
   7245         for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   7246             if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
   7247                 ret = m_channels[i]->switchChannelCb(camMaster);
   7248                 if (ret != NO_ERROR) {
   7249                     LOGE("Channel Switch Failed");
   7250                     break;
   7251                 }
   7252             }
   7253         }
   7254 
   7255         if (mMasterCamera != camMaster) {
   7256             if (ret == NO_ERROR) {
   7257                 //Trigger Event to modules to update Master info
   7258                 mParameters.setSwitchCamera(camMaster);
   7259             }
   7260         }
   7261         // Update master camera
   7262         mMasterCamera = camMaster;
   7263     }
   7264 
   7265     return ret;
   7266 }
   7267 
   7268 /*===========================================================================
   7269  * FUNCTION   : lockAPI
   7270  *
   7271  * DESCRIPTION: lock to process API
   7272  *
   7273  * PARAMETERS : none
   7274  *
   7275  * RETURN     : none
   7276  *==========================================================================*/
   7277 void QCamera2HardwareInterface::lockAPI()
   7278 {
   7279     pthread_mutex_lock(&m_lock);
   7280 }
   7281 
   7282 /*===========================================================================
   7283  * FUNCTION   : waitAPIResult
   7284  *
   7285  * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
   7286  *              return only cerntain API event type arrives
   7287  *
   7288  * PARAMETERS :
   7289  *   @api_evt : API event type
   7290  *
   7291  * RETURN     : none
   7292  *==========================================================================*/
   7293 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
   7294         qcamera_api_result_t *apiResult)
   7295 {
   7296     LOGD("wait for API result of evt (%d)", api_evt);
   7297     int resultReceived = 0;
   7298     while  (!resultReceived) {
   7299         pthread_cond_wait(&m_cond, &m_lock);
   7300         if (m_apiResultList != NULL) {
   7301             api_result_list *apiResultList = m_apiResultList;
   7302             api_result_list *apiResultListPrevious = m_apiResultList;
   7303             while (apiResultList != NULL) {
   7304                 if (apiResultList->result.request_api == api_evt) {
   7305                     resultReceived = 1;
   7306                     *apiResult = apiResultList->result;
   7307                     apiResultListPrevious->next = apiResultList->next;
   7308                     if (apiResultList == m_apiResultList) {
   7309                         m_apiResultList = apiResultList->next;
   7310                     }
   7311                     free(apiResultList);
   7312                     break;
   7313                 }
   7314                 else {
   7315                     apiResultListPrevious = apiResultList;
   7316                     apiResultList = apiResultList->next;
   7317                 }
   7318             }
   7319         }
   7320     }
   7321     LOGD("return (%d) from API result wait for evt (%d)",
   7322            apiResult->status, api_evt);
   7323 }
   7324 
   7325 
   7326 /*===========================================================================
   7327  * FUNCTION   : unlockAPI
   7328  *
   7329  * DESCRIPTION: API processing is done, unlock
   7330  *
   7331  * PARAMETERS : none
   7332  *
   7333  * RETURN     : none
   7334  *==========================================================================*/
   7335 void QCamera2HardwareInterface::unlockAPI()
   7336 {
   7337     pthread_mutex_unlock(&m_lock);
   7338 }
   7339 
   7340 /*===========================================================================
   7341  * FUNCTION   : signalAPIResult
   7342  *
   7343  * DESCRIPTION: signal condition viarable that cerntain API event type arrives
   7344  *
   7345  * PARAMETERS :
   7346  *   @result  : API result
   7347  *
   7348  * RETURN     : none
   7349  *==========================================================================*/
   7350 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
   7351 {
   7352 
   7353     pthread_mutex_lock(&m_lock);
   7354     api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
   7355     if (apiResult == NULL) {
   7356         LOGE("ERROR: malloc for api result failed, Result will not be sent");
   7357         goto malloc_failed;
   7358     }
   7359     apiResult->result = *result;
   7360     apiResult->next = NULL;
   7361     if (m_apiResultList == NULL) m_apiResultList = apiResult;
   7362     else {
   7363         api_result_list *apiResultList = m_apiResultList;
   7364         while(apiResultList->next != NULL) apiResultList = apiResultList->next;
   7365         apiResultList->next = apiResult;
   7366     }
   7367 malloc_failed:
   7368     pthread_cond_broadcast(&m_cond);
   7369     pthread_mutex_unlock(&m_lock);
   7370 }
   7371 
   7372 /*===========================================================================
   7373  * FUNCTION   : signalEvtResult
   7374  *
   7375  * DESCRIPTION: signal condition variable that certain event was processed
   7376  *
   7377  * PARAMETERS :
   7378  *   @result  : Event result
   7379  *
   7380  * RETURN     : none
   7381  *==========================================================================*/
   7382 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
   7383 {
   7384     pthread_mutex_lock(&m_evtLock);
   7385     m_evtResult = *result;
   7386     pthread_cond_signal(&m_evtCond);
   7387     pthread_mutex_unlock(&m_evtLock);
   7388 }
   7389 
   7390 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
   7391 {
   7392     int32_t rc = NO_ERROR;
   7393     cam_dimension_t str_dim,max_dim;
   7394     QCameraChannel *pChannel;
   7395 
   7396     max_dim.width = 0;
   7397     max_dim.height = 0;
   7398 
   7399     for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
   7400         if (m_channels[j] != NULL) {
   7401             pChannel = m_channels[j];
   7402             for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
   7403                 QCameraStream *pStream = pChannel->getStreamByIndex(i);
   7404                 if (pStream != NULL) {
   7405                     if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
   7406                             || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
   7407                         continue;
   7408                     }
   7409                     pStream->getFrameDimension(str_dim);
   7410                     if (str_dim.width > max_dim.width) {
   7411                         max_dim.width = str_dim.width;
   7412                     }
   7413                     if (str_dim.height > max_dim.height) {
   7414                         max_dim.height = str_dim.height;
   7415                     }
   7416                 }
   7417             }
   7418         }
   7419     }
   7420 
   7421     for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
   7422         QCameraStream *pStream = curChannel->getStreamByIndex(i);
   7423         if (pStream != NULL) {
   7424             if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
   7425                     || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
   7426                 continue;
   7427             }
   7428             pStream->getFrameDimension(str_dim);
   7429             if (str_dim.width > max_dim.width) {
   7430                 max_dim.width = str_dim.width;
   7431             }
   7432             if (str_dim.height > max_dim.height) {
   7433                 max_dim.height = str_dim.height;
   7434             }
   7435         }
   7436     }
   7437     rc = mParameters.updateRAW(max_dim);
   7438     return rc;
   7439 }
   7440 
   7441 /*===========================================================================
   7442  * FUNCTION   : getPaddingInfo
   7443  *
   7444  * DESCRIPTION: calculate padding per stream
   7445  *
   7446  * PARAMETERS :
   7447  *   @streamType  : type of stream to be added
   7448  *   @padding_info : Padding info. Output
   7449  *
   7450  * RETURN     : int32_t type of status
   7451  *              NO_ERROR  -- success
   7452  *              none-zero failure code
   7453  *==========================================================================*/
   7454 int32_t QCamera2HardwareInterface::getPaddingInfo(cam_stream_type_t streamType,
   7455         cam_padding_info_t *padding_info)
   7456 {
   7457     int32_t rc = NO_ERROR;
   7458     if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
   7459         cam_analysis_info_t analysisInfo;
   7460         cam_feature_mask_t featureMask;
   7461 
   7462         featureMask = 0;
   7463         mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask);
   7464         rc = mParameters.getAnalysisInfo(
   7465                 ((mParameters.getRecordingHintValue() == true) &&
   7466                  mParameters.fdModeInVideo()),
   7467                 featureMask,
   7468                 &analysisInfo);
   7469         if (rc != NO_ERROR) {
   7470             LOGE("getAnalysisInfo failed, ret = %d", rc);
   7471             return rc;
   7472         }
   7473 
   7474         *padding_info = analysisInfo.analysis_padding_info;
   7475     } else {
   7476         *padding_info =
   7477                 gCamCapability[mCameraId]->padding_info;
   7478         if (streamType == CAM_STREAM_TYPE_PREVIEW || streamType == CAM_STREAM_TYPE_POSTVIEW) {
   7479             padding_info->width_padding = mSurfaceStridePadding;
   7480             padding_info->height_padding = CAM_PAD_TO_2;
   7481         }
   7482         if((!needReprocess())
   7483                 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
   7484                 || (!mParameters.isLLNoiseEnabled())) {
   7485             padding_info->offset_info.offset_x = 0;
   7486             padding_info->offset_info.offset_y = 0;
   7487         }
   7488     }
   7489     return rc;
   7490 }
   7491 
   7492 /*===========================================================================
   7493  * FUNCTION   : addStreamToChannel
   7494  *
   7495  * DESCRIPTION: add a stream into a channel
   7496  *
   7497  * PARAMETERS :
   7498  *   @pChannel   : ptr to channel obj
   7499  *   @streamType : type of stream to be added
   7500  *   @streamCB   : callback of stream
   7501  *   @userData   : user data ptr to callback
   7502  *
   7503  * RETURN     : int32_t type of status
   7504  *              NO_ERROR  -- success
   7505  *              none-zero failure code
   7506  *==========================================================================*/
   7507 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
   7508                                                       cam_stream_type_t streamType,
   7509                                                       stream_cb_routine streamCB,
   7510                                                       void *userData)
   7511 {
   7512     int32_t rc = NO_ERROR;
   7513     QCameraHeapMemory *pStreamInfo = NULL;
   7514     uint32_t cam_type = MM_CAMERA_TYPE_MAIN;
   7515     bool needAuxStream = FALSE;
   7516 
   7517     if (streamType == CAM_STREAM_TYPE_RAW) {
   7518         prepareRawStream(pChannel);
   7519     }
   7520 
   7521     if (isDualCamera()) {
   7522         if (!((mParameters.isDCmAsymmetricSnapMode()) &&
   7523                 (streamType == CAM_STREAM_TYPE_SNAPSHOT))) {
   7524             cam_type |= MM_CAMERA_TYPE_AUX;
   7525         } else {
   7526             needAuxStream = TRUE;
   7527         }
   7528     }
   7529 
   7530     pStreamInfo = allocateStreamInfoBuf(streamType,
   7531             getStreamRefCount(streamType, cam_type), cam_type);
   7532     if (pStreamInfo == NULL) {
   7533         LOGE("no mem for stream info buf");
   7534         return NO_MEMORY;
   7535     }
   7536 
   7537     bool bDynAllocBuf = false;
   7538     if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
   7539         bDynAllocBuf = true;
   7540     }
   7541 
   7542     cam_padding_info_t padding_info;
   7543     getPaddingInfo(streamType, &padding_info);
   7544 
   7545     bool deferAllocation = needDeferred(streamType);
   7546     LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
   7547             deferAllocation, bDynAllocBuf, streamType);
   7548     rc = pChannel->addStream(*this,
   7549             pStreamInfo, NULL, &padding_info,
   7550             streamCB, userData, bDynAllocBuf,
   7551             deferAllocation, ROTATE_0, cam_type);
   7552 
   7553     if (rc != NO_ERROR) {
   7554         LOGE("add stream type (%d) cam = %d failed, ret = %d",
   7555                streamType, cam_type, rc);
   7556         return rc;
   7557     }
   7558 
   7559     /*Add stream for Asymmetric dual camera use case*/
   7560     if (needAuxStream) {
   7561         cam_type = MM_CAMERA_TYPE_AUX;
   7562         pStreamInfo = allocateStreamInfoBuf(streamType,
   7563                 getStreamRefCount(streamType, cam_type), cam_type);
   7564         if (pStreamInfo == NULL) {
   7565             LOGE("no mem for stream info buf");
   7566             return NO_MEMORY;
   7567         }
   7568         rc = pChannel->addStream(*this,
   7569                 pStreamInfo, NULL, &padding_info,
   7570                 streamCB, userData, bDynAllocBuf,
   7571                 deferAllocation, ROTATE_0, cam_type);
   7572         if (rc != NO_ERROR) {
   7573             LOGE("add stream type (%d) cam = %d failed, ret = %d",
   7574                    streamType, cam_type, rc);
   7575             return rc;
   7576         }
   7577     }
   7578     return rc;
   7579 }
   7580 
   7581 /*===========================================================================
   7582  * FUNCTION   : addPreviewChannel
   7583  *
   7584  * DESCRIPTION: add a preview channel that contains a preview stream
   7585  *
   7586  * PARAMETERS : none
   7587  *
   7588  * RETURN     : int32_t type of status
   7589  *              NO_ERROR  -- success
   7590  *              none-zero failure code
   7591  *==========================================================================*/
   7592 int32_t QCamera2HardwareInterface::addPreviewChannel()
   7593 {
   7594     int32_t rc = NO_ERROR;
   7595     QCameraChannel *pChannel = NULL;
   7596     char value[PROPERTY_VALUE_MAX];
   7597     bool raw_yuv = false;
   7598 
   7599 
   7600     if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   7601         // if we had preview channel before, delete it first
   7602         delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
   7603         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
   7604     }
   7605 
   7606     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
   7607     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7608     if (NULL == pChannel) {
   7609         LOGE("no mem for preview channel");
   7610         return NO_MEMORY;
   7611     }
   7612 
   7613     // preview only channel, don't need bundle attr and cb
   7614     rc = pChannel->init(NULL, NULL, NULL);
   7615     if (rc != NO_ERROR) {
   7616         LOGE("init preview channel failed, ret = %d", rc);
   7617         delete pChannel;
   7618         return rc;
   7619     }
   7620 
   7621     // meta data stream always coexists with preview if applicable
   7622     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7623             metadata_stream_cb_routine, this);
   7624     if (rc != NO_ERROR) {
   7625         LOGE("add metadata stream failed, ret = %d", rc);
   7626         delete pChannel;
   7627         return rc;
   7628     }
   7629 
   7630     if (isRdiMode()) {
   7631         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   7632                 rdi_mode_stream_cb_routine, this);
   7633     } else {
   7634         if (isNoDisplayMode()) {
   7635             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7636                     nodisplay_preview_stream_cb_routine, this);
   7637         } else {
   7638             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7639                     preview_stream_cb_routine, this);
   7640             if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
   7641                 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   7642                         synchronous_stream_cb_routine);
   7643             }
   7644         }
   7645     }
   7646 
   7647     if (rc != NO_ERROR) {
   7648         LOGE("add raw/preview stream failed, ret = %d", rc);
   7649         delete pChannel;
   7650         return rc;
   7651     }
   7652 
   7653     if (((mParameters.fdModeInVideo())
   7654             || (mParameters.getDcrf() == true)
   7655             || (mParameters.getRecordingHintValue() != true))
   7656             && (!isSecureMode())) {
   7657         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   7658                 NULL, this);
   7659         if (rc != NO_ERROR) {
   7660             LOGE("add Analysis stream failed, ret = %d", rc);
   7661             delete pChannel;
   7662             return rc;
   7663         }
   7664     }
   7665 
   7666     property_get("persist.camera.raw_yuv", value, "0");
   7667     raw_yuv = atoi(value) > 0 ? true : false;
   7668     if ( raw_yuv ) {
   7669         rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
   7670                 preview_raw_stream_cb_routine,this);
   7671         if ( rc != NO_ERROR ) {
   7672             LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
   7673             delete pChannel;
   7674             return rc;
   7675         }
   7676     }
   7677 
   7678     if (rc != NO_ERROR) {
   7679         LOGE("add preview stream failed, ret = %d", rc);
   7680         delete pChannel;
   7681         return rc;
   7682     }
   7683 
   7684     m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
   7685     return rc;
   7686 }
   7687 
   7688 /*===========================================================================
   7689  * FUNCTION   : addVideoChannel
   7690  *
   7691  * DESCRIPTION: add a video channel that contains a video stream
   7692  *
   7693  * PARAMETERS : none
   7694  *
   7695  * RETURN     : int32_t type of status
   7696  *              NO_ERROR  -- success
   7697  *              none-zero failure code
   7698  *==========================================================================*/
   7699 int32_t QCamera2HardwareInterface::addVideoChannel()
   7700 {
   7701     int32_t rc = NO_ERROR;
   7702     QCameraVideoChannel *pChannel = NULL;
   7703 
   7704     if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
   7705         // if we had video channel before, delete it first
   7706         delete m_channels[QCAMERA_CH_TYPE_VIDEO];
   7707         m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
   7708     }
   7709 
   7710     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
   7711     pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
   7712     if (NULL == pChannel) {
   7713         LOGE("no mem for video channel");
   7714         return NO_MEMORY;
   7715     }
   7716 
   7717     if (isLowPowerMode()) {
   7718         mm_camera_channel_attr_t attr;
   7719         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7720         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7721         attr.look_back = 0; //wait for future frame for liveshot
   7722         attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7723         attr.water_mark = 1; //hold min buffers possible in Q
   7724         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7725         rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
   7726     } else {
   7727         // preview only channel, don't need bundle attr and cb
   7728         rc = pChannel->init(NULL, NULL, NULL);
   7729     }
   7730 
   7731     if (rc != 0) {
   7732         LOGE("init video channel failed, ret = %d", rc);
   7733         delete pChannel;
   7734         return rc;
   7735     }
   7736 
   7737     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
   7738             video_stream_cb_routine, this);
   7739 
   7740     if (rc != NO_ERROR) {
   7741         LOGE("add video stream failed, ret = %d", rc);
   7742         delete pChannel;
   7743         return rc;
   7744     }
   7745 
   7746     m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
   7747     return rc;
   7748 }
   7749 
   7750 /*===========================================================================
   7751  * FUNCTION   : addSnapshotChannel
   7752  *
   7753  * DESCRIPTION: add a snapshot channel that contains a snapshot stream
   7754  *
   7755  * PARAMETERS : none
   7756  *
   7757  * RETURN     : int32_t type of status
   7758  *              NO_ERROR  -- success
   7759  *              none-zero failure code
   7760  * NOTE       : Add this channel for live snapshot usecase. Regular capture will
   7761  *              use addCaptureChannel.
   7762  *==========================================================================*/
   7763 int32_t QCamera2HardwareInterface::addSnapshotChannel()
   7764 {
   7765     int32_t rc = NO_ERROR;
   7766     QCameraChannel *pChannel = NULL;
   7767 
   7768     if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
   7769         // if we had ZSL channel before, delete it first
   7770         delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   7771         m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
   7772     }
   7773 
   7774     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   7775     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7776     if (NULL == pChannel) {
   7777         LOGE("no mem for snapshot channel");
   7778         return NO_MEMORY;
   7779     }
   7780 
   7781     mm_camera_channel_attr_t attr;
   7782     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7783     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   7784     attr.look_back = 0; //wait for future frame for liveshot
   7785     attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7786     attr.water_mark = 1; //hold min buffers possible in Q
   7787     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7788     attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
   7789     rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
   7790     if (rc != NO_ERROR) {
   7791         LOGE("init snapshot channel failed, ret = %d", rc);
   7792         delete pChannel;
   7793         return rc;
   7794     }
   7795 
   7796     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   7797             NULL, NULL);
   7798     if (rc != NO_ERROR) {
   7799         LOGE("add snapshot stream failed, ret = %d", rc);
   7800         delete pChannel;
   7801         return rc;
   7802     }
   7803 
   7804     m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
   7805     return rc;
   7806 }
   7807 
   7808 /*===========================================================================
   7809  * FUNCTION   : addRawChannel
   7810  *
   7811  * DESCRIPTION: add a raw channel that contains a raw image stream
   7812  *
   7813  * PARAMETERS : none
   7814  *
   7815  * RETURN     : int32_t type of status
   7816  *              NO_ERROR  -- success
   7817  *              none-zero failure code
   7818  *==========================================================================*/
   7819 int32_t QCamera2HardwareInterface::addRawChannel()
   7820 {
   7821     int32_t rc = NO_ERROR;
   7822     QCameraChannel *pChannel = NULL;
   7823 
   7824     if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
   7825         // if we had raw channel before, delete it first
   7826         delete m_channels[QCAMERA_CH_TYPE_RAW];
   7827         m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
   7828     }
   7829 
   7830     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
   7831     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7832     if (NULL == pChannel) {
   7833         LOGE("no mem for raw channel");
   7834         return NO_MEMORY;
   7835     }
   7836 
   7837     if (mParameters.getofflineRAW()) {
   7838         mm_camera_channel_attr_t attr;
   7839         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7840         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7841         attr.look_back = mParameters.getZSLBackLookCount();
   7842         attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7843         attr.water_mark = 1;
   7844         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7845         rc = pChannel->init(&attr, raw_channel_cb_routine, this);
   7846         if (rc != NO_ERROR) {
   7847             LOGE("init RAW channel failed, ret = %d", rc);
   7848             delete pChannel;
   7849             return rc;
   7850         }
   7851     } else {
   7852         rc = pChannel->init(NULL, NULL, NULL);
   7853         if (rc != NO_ERROR) {
   7854             LOGE("init raw channel failed, ret = %d", rc);
   7855             delete pChannel;
   7856             return rc;
   7857         }
   7858     }
   7859 
   7860     if (!mParameters.isZSLMode()) {
   7861         // meta data stream always coexists with snapshot in regular RAW capture case
   7862         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7863                 metadata_stream_cb_routine, this);
   7864         if (rc != NO_ERROR) {
   7865             LOGE("add metadata stream failed, ret = %d", rc);
   7866             delete pChannel;
   7867             return rc;
   7868         }
   7869     }
   7870 
   7871     if (mParameters.getofflineRAW()) {
   7872         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   7873                 NULL, this);
   7874     } else if(isSecureMode()) {
   7875         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   7876                 secure_stream_cb_routine, this);
   7877     } else {
   7878         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   7879                 raw_stream_cb_routine, this);
   7880     }
   7881     if (rc != NO_ERROR) {
   7882         LOGE("add snapshot stream failed, ret = %d", rc);
   7883         delete pChannel;
   7884         return rc;
   7885     }
   7886     m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
   7887     return rc;
   7888 }
   7889 
   7890 /*===========================================================================
   7891  * FUNCTION   : addZSLChannel
   7892  *
   7893  * DESCRIPTION: add a ZSL channel that contains a preview stream and
   7894  *              a snapshot stream
   7895  *
   7896  * PARAMETERS : none
   7897  *
   7898  * RETURN     : int32_t type of status
   7899  *              NO_ERROR  -- success
   7900  *              none-zero failure code
   7901  *==========================================================================*/
   7902 int32_t QCamera2HardwareInterface::addZSLChannel()
   7903 {
   7904     int32_t rc = NO_ERROR;
   7905     QCameraPicChannel *pChannel = NULL;
   7906     char value[PROPERTY_VALUE_MAX];
   7907     bool raw_yuv = false;
   7908 
   7909     if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
   7910         // if we had ZSL channel before, delete it first
   7911         delete m_channels[QCAMERA_CH_TYPE_ZSL];
   7912         m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
   7913     }
   7914 
   7915     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
   7916     pChannel = new QCameraPicChannel(handle,
   7917                                      mCameraHandle->ops);
   7918     if (NULL == pChannel) {
   7919         LOGE("no mem for ZSL channel");
   7920         return NO_MEMORY;
   7921     }
   7922 
   7923     // ZSL channel, init with bundle attr and cb
   7924     mm_camera_channel_attr_t attr;
   7925     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7926     if (mParameters.isSceneSelectionEnabled()) {
   7927         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   7928     } else {
   7929         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7930     }
   7931     attr.look_back = mParameters.getZSLBackLookCount();
   7932     attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7933     if (mParameters.isOEMFeatEnabled()) {
   7934         LOGD("EDGE SMOOTH frameskip enabled");
   7935         attr.post_frame_skip += mParameters.isOEMFeatFrameSkipEnabled();
   7936     }
   7937     attr.water_mark = mParameters.getZSLQueueDepth();
   7938     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7939     attr.user_expected_frame_id =
   7940         mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
   7941 
   7942     //Enabled matched queue
   7943     if (isFrameSyncEnabled()) {
   7944         LOGH("Enabling frame sync for dual camera, camera Id: %d",
   7945                  mCameraId);
   7946         attr.enable_frame_sync = 1;
   7947     }
   7948     rc = pChannel->init(&attr,
   7949                         zsl_channel_cb,
   7950                         this);
   7951     if (rc != 0) {
   7952         LOGE("init ZSL channel failed, ret = %d", rc);
   7953         delete pChannel;
   7954         return rc;
   7955     }
   7956 
   7957     // meta data stream always coexists with preview if applicable
   7958     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7959             metadata_stream_cb_routine, this);
   7960     if (rc != NO_ERROR) {
   7961         LOGE("add metadata stream failed, ret = %d", rc);
   7962         delete pChannel;
   7963         return rc;
   7964     }
   7965 
   7966     if (isNoDisplayMode()) {
   7967         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7968                 nodisplay_preview_stream_cb_routine, this);
   7969     } else {
   7970         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7971                 preview_stream_cb_routine, this);
   7972         if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
   7973             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   7974                     synchronous_stream_cb_routine);
   7975         }
   7976     }
   7977     if (rc != NO_ERROR) {
   7978         LOGE("add preview stream failed, ret = %d", rc);
   7979         delete pChannel;
   7980         return rc;
   7981     }
   7982 
   7983     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   7984             NULL, this);
   7985     if (rc != NO_ERROR) {
   7986         LOGE("add snapshot stream failed, ret = %d", rc);
   7987         delete pChannel;
   7988         return rc;
   7989     }
   7990 
   7991     if (!isSecureMode()) {
   7992         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   7993                 NULL, this);
   7994         if (rc != NO_ERROR) {
   7995             LOGE("add Analysis stream failed, ret = %d", rc);
   7996             delete pChannel;
   7997             return rc;
   7998         }
   7999     }
   8000 
   8001     property_get("persist.camera.raw_yuv", value, "0");
   8002     raw_yuv = atoi(value) > 0 ? true : false;
   8003     if (raw_yuv) {
   8004         rc = addStreamToChannel(pChannel,
   8005                                 CAM_STREAM_TYPE_RAW,
   8006                                 preview_raw_stream_cb_routine,
   8007                                 this);
   8008         if (rc != NO_ERROR) {
   8009             LOGE("add raw stream failed, ret = %d", rc);
   8010             delete pChannel;
   8011             return rc;
   8012         }
   8013     }
   8014 
   8015     m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
   8016     return rc;
   8017 }
   8018 
   8019 /*===========================================================================
   8020  * FUNCTION   : addCaptureChannel
   8021  *
   8022  * DESCRIPTION: add a capture channel that contains a snapshot stream
   8023  *              and a postview stream
   8024  *
   8025  * PARAMETERS : none
   8026  *
   8027  * RETURN     : int32_t type of status
   8028  *              NO_ERROR  -- success
   8029  *              none-zero failure code
   8030  * NOTE       : Add this channel for regular capture usecase.
   8031  *              For Live snapshot usecase, use addSnapshotChannel.
   8032  *==========================================================================*/
   8033 int32_t QCamera2HardwareInterface::addCaptureChannel()
   8034 {
   8035     int32_t rc = NO_ERROR;
   8036     QCameraPicChannel *pChannel = NULL;
   8037     char value[PROPERTY_VALUE_MAX];
   8038     bool raw_yuv = false;
   8039 
   8040     if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
   8041         delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
   8042         m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
   8043     }
   8044 
   8045     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
   8046     pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
   8047     if (NULL == pChannel) {
   8048         LOGE("no mem for capture channel");
   8049         return NO_MEMORY;
   8050     }
   8051 
   8052     // Capture channel, only need snapshot and postview streams start together
   8053     mm_camera_channel_attr_t attr;
   8054     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   8055     if ( mLongshotEnabled ) {
   8056         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   8057         attr.look_back = mParameters.getZSLBackLookCount();
   8058         attr.water_mark = mParameters.getZSLQueueDepth();
   8059     } else {
   8060         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   8061     }
   8062     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   8063 
   8064     rc = pChannel->init(&attr,
   8065                         capture_channel_cb_routine,
   8066                         this);
   8067     if (rc != NO_ERROR) {
   8068         LOGE("init capture channel failed, ret = %d", rc);
   8069         delete pChannel;
   8070         return rc;
   8071     }
   8072 
   8073     // meta data stream always coexists with snapshot in regular capture case
   8074     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   8075             metadata_stream_cb_routine, this);
   8076     if (rc != NO_ERROR) {
   8077         LOGE("add metadata stream failed, ret = %d", rc);
   8078         delete pChannel;
   8079         return rc;
   8080     }
   8081 
   8082     if (mLongshotEnabled) {
   8083         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   8084                 preview_stream_cb_routine, this);
   8085         if (rc != NO_ERROR) {
   8086             LOGE("add preview stream failed, ret = %d", rc);
   8087             delete pChannel;
   8088             return rc;
   8089         }
   8090         if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
   8091             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   8092                     synchronous_stream_cb_routine);
   8093         }
   8094     //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
   8095     } else if (!mParameters.getQuadraCfa()) {
   8096         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
   8097                                 NULL, this);
   8098         if (rc != NO_ERROR) {
   8099             LOGE("add postview stream failed, ret = %d", rc);
   8100             delete pChannel;
   8101             return rc;
   8102         }
   8103     }
   8104 
   8105     if (!mParameters.getofflineRAW()) {
   8106         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   8107                 NULL, this);
   8108         if (rc != NO_ERROR) {
   8109             LOGE("add snapshot stream failed, ret = %d", rc);
   8110             delete pChannel;
   8111             return rc;
   8112         }
   8113     }
   8114 
   8115     stream_cb_routine stream_cb = NULL;
   8116     property_get("persist.camera.raw_yuv", value, "0");
   8117     raw_yuv = atoi(value) > 0 ? true : false;
   8118 
   8119     if (raw_yuv) {
   8120         stream_cb = snapshot_raw_stream_cb_routine;
   8121     }
   8122 
   8123     if ((raw_yuv) || (mParameters.getofflineRAW())) {
   8124         rc = addStreamToChannel(pChannel,
   8125                 CAM_STREAM_TYPE_RAW, stream_cb, this);
   8126         if (rc != NO_ERROR) {
   8127             LOGE("add raw stream failed, ret = %d", rc);
   8128             delete pChannel;
   8129             return rc;
   8130         }
   8131     }
   8132 
   8133     m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
   8134     return rc;
   8135 }
   8136 
   8137 /*===========================================================================
   8138  * FUNCTION   : addMetaDataChannel
   8139  *
   8140  * DESCRIPTION: add a meta data channel that contains a metadata stream
   8141  *
   8142  * PARAMETERS : none
   8143  *
   8144  * RETURN     : int32_t type of status
   8145  *              NO_ERROR  -- success
   8146  *              none-zero failure code
   8147  *==========================================================================*/
   8148 int32_t QCamera2HardwareInterface::addMetaDataChannel()
   8149 {
   8150     int32_t rc = NO_ERROR;
   8151     QCameraChannel *pChannel = NULL;
   8152 
   8153     if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
   8154         delete m_channels[QCAMERA_CH_TYPE_METADATA];
   8155         m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
   8156     }
   8157 
   8158     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
   8159     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   8160     if (NULL == pChannel) {
   8161         LOGE("no mem for metadata channel");
   8162         return NO_MEMORY;
   8163     }
   8164 
   8165     rc = pChannel->init(NULL,
   8166                         NULL,
   8167                         NULL);
   8168     if (rc != NO_ERROR) {
   8169         LOGE("init metadata channel failed, ret = %d", rc);
   8170         delete pChannel;
   8171         return rc;
   8172     }
   8173 
   8174     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   8175             metadata_stream_cb_routine, this);
   8176     if (rc != NO_ERROR) {
   8177         LOGE("add metadata stream failed, ret = %d", rc);
   8178         delete pChannel;
   8179         return rc;
   8180     }
   8181 
   8182     m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
   8183     return rc;
   8184 }
   8185 
   8186 /*===========================================================================
   8187  * FUNCTION   : addCallbackChannel
   8188  *
   8189  * DESCRIPTION: add a callback channel that contains a callback stream
   8190  *
   8191  * PARAMETERS : none
   8192  *
   8193  * RETURN     : int32_t type of status
   8194  *              NO_ERROR  -- success
   8195  *              none-zero failure code
   8196  *==========================================================================*/
   8197 int32_t QCamera2HardwareInterface::addCallbackChannel()
   8198 {
   8199     int32_t rc = NO_ERROR;
   8200     QCameraChannel *pChannel = NULL;
   8201 
   8202     if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
   8203         delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
   8204         m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
   8205     }
   8206 
   8207     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
   8208     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   8209     if (NULL == pChannel) {
   8210         LOGE("no mem for callback channel");
   8211         return NO_MEMORY;
   8212     }
   8213 
   8214     rc = pChannel->init(NULL, NULL, this);
   8215     if (rc != NO_ERROR) {
   8216         LOGE("init callback channel failed, ret = %d",
   8217                  rc);
   8218         delete pChannel;
   8219         return rc;
   8220     }
   8221 
   8222     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
   8223             callback_stream_cb_routine, this);
   8224     if (rc != NO_ERROR) {
   8225         LOGE("add callback stream failed, ret = %d", rc);
   8226         delete pChannel;
   8227         return rc;
   8228     }
   8229 
   8230     m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
   8231     return rc;
   8232 }
   8233 
   8234 
   8235 /*===========================================================================
   8236  * FUNCTION   : addAnalysisChannel
   8237  *
   8238  * DESCRIPTION: add a analysis channel that contains a analysis stream
   8239  *
   8240  * PARAMETERS : none
   8241  *
   8242  * RETURN     : int32_t type of status
   8243  *              NO_ERROR  -- success
   8244  *              none-zero failure code
   8245  *==========================================================================*/
   8246 int32_t QCamera2HardwareInterface::addAnalysisChannel()
   8247 {
   8248     int32_t rc = NO_ERROR;
   8249     QCameraChannel *pChannel = NULL;
   8250 
   8251     if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
   8252         delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
   8253         m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
   8254     }
   8255 
   8256     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
   8257     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   8258     if (NULL == pChannel) {
   8259         LOGE("no mem for metadata channel");
   8260         return NO_MEMORY;
   8261     }
   8262 
   8263     rc = pChannel->init(NULL, NULL, this);
   8264     if (rc != NO_ERROR) {
   8265         LOGE("init Analysis channel failed, ret = %d", rc);
   8266         delete pChannel;
   8267         return rc;
   8268     }
   8269 
   8270     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   8271             NULL, this);
   8272     if (rc != NO_ERROR) {
   8273         LOGE("add Analysis stream failed, ret = %d", rc);
   8274         delete pChannel;
   8275         return rc;
   8276     }
   8277 
   8278     m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
   8279     return rc;
   8280 }
   8281 
   8282 
   8283 /*===========================================================================
   8284  * FUNCTION   : getPPConfig
   8285  *
   8286  * DESCRIPTION: get Post processing configaration data
   8287  *
   8288  * PARAMETERS :
   8289  * @pp config:  pp config structure pointer,
   8290  * @curIndex:  current pp channel index
   8291  * @multipass: Flag if multipass prcessing enabled.
   8292  *
   8293  * RETURN     : int32_t type of status
   8294  *              NO_ERROR  -- success
   8295  *              none-zero failure code
   8296  *==========================================================================*/
   8297 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
   8298         int8_t curIndex, bool multipass)
   8299 {
   8300     int32_t rc = NO_ERROR;
   8301     int32_t feature_set = 0;
   8302 
   8303     if (multipass) {
   8304         LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
   8305                 mParameters.getReprocCount(), curIndex);
   8306     }
   8307 
   8308     LOGH("Supported pproc feature mask = %llx",
   8309             gCamCapability[mCameraId]->qcom_supported_feature_mask);
   8310     cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
   8311     int32_t zoomLevel = mParameters.getParmZoomLevel();
   8312     uint32_t rotation = mParameters.getJpegRotation();
   8313     int32_t effect = mParameters.getEffectValue();
   8314 
   8315     pp_config.cur_reproc_count = curIndex + 1;
   8316     pp_config.total_reproc_count = mParameters.getReprocCount();
   8317 
   8318     //Checking what feature mask to enable
   8319     if (curIndex == 0) {
   8320         if (mParameters.getQuadraCfa()) {
   8321             feature_set = 2;
   8322         } else {
   8323             feature_set = 0;
   8324         }
   8325     } else if (curIndex == 1) {
   8326         if (mParameters.getQuadraCfa()) {
   8327             feature_set = 0;
   8328         } else {
   8329             feature_set = 1;
   8330         }
   8331     }
   8332 
   8333     switch(feature_set) {
   8334         case 0:
   8335             //Configure feature mask for first pass of reprocessing
   8336             //check if any effects are enabled
   8337             if ((CAM_EFFECT_MODE_OFF != effect) &&
   8338                 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
   8339                 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
   8340                 pp_config.effect = effect;
   8341             }
   8342 
   8343             //check for features that need to be enabled by default like sharpness
   8344             //(if supported by hw).
   8345             if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
   8346                 !mParameters.isOptiZoomEnabled()) {
   8347                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
   8348                 pp_config.sharpness = mParameters.getSharpness();
   8349             }
   8350 
   8351             //check if zoom is enabled
   8352             if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
   8353                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   8354             }
   8355 
   8356             if (mParameters.isWNREnabled() &&
   8357                 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
   8358                 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
   8359                 pp_config.denoise2d.denoise_enable = 1;
   8360                 pp_config.denoise2d.process_plates =
   8361                         mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
   8362             }
   8363 
   8364             if (isCACEnabled()) {
   8365                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
   8366             }
   8367 
   8368             //check if rotation is required
   8369             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
   8370                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
   8371                 if (rotation == 0) {
   8372                     pp_config.rotation = ROTATE_0;
   8373                 } else if (rotation == 90) {
   8374                     pp_config.rotation = ROTATE_90;
   8375                 } else if (rotation == 180) {
   8376                     pp_config.rotation = ROTATE_180;
   8377                 } else if (rotation == 270) {
   8378                     pp_config.rotation = ROTATE_270;
   8379                 }
   8380             }
   8381 
   8382             if (mParameters.isHDREnabled()){
   8383                 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
   8384                 pp_config.hdr_param.hdr_enable = 1;
   8385                 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
   8386                 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
   8387             } else {
   8388                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
   8389                 pp_config.hdr_param.hdr_enable = 0;
   8390             }
   8391 
   8392             //check if scaling is enabled
   8393             if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
   8394                 mParameters.isReprocScaleEnabled() &&
   8395                 mParameters.isUnderReprocScaling()){
   8396                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   8397                 mParameters.getPicSizeFromAPK(
   8398                         pp_config.scale_param.output_width,
   8399                         pp_config.scale_param.output_height);
   8400             }
   8401 
   8402             if(mParameters.isUbiFocusEnabled()) {
   8403                 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
   8404             } else {
   8405                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
   8406             }
   8407 
   8408             if(mParameters.isUbiRefocus()) {
   8409                 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
   8410                 pp_config.misc_buf_param.misc_buffer_index = 0;
   8411             } else {
   8412                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
   8413             }
   8414 
   8415             if(mParameters.isChromaFlashEnabled()) {
   8416                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
   8417                 pp_config.flash_value = CAM_FLASH_ON;
   8418             } else {
   8419                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
   8420             }
   8421 
   8422             if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
   8423                 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
   8424                 pp_config.zoom_level = (uint8_t) zoomLevel;
   8425             } else {
   8426                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
   8427             }
   8428 
   8429             if (mParameters.getofflineRAW()) {
   8430                 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
   8431             }
   8432 
   8433             if (mParameters.isTruePortraitEnabled()) {
   8434                 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
   8435                 pp_config.misc_buf_param.misc_buffer_index = 0;
   8436             } else {
   8437                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
   8438             }
   8439 
   8440             if(mParameters.isStillMoreEnabled()) {
   8441                 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
   8442             } else {
   8443                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
   8444             }
   8445 
   8446             if (mParameters.isOEMFeatEnabled()) {
   8447                 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
   8448             }
   8449 
   8450             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
   8451                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
   8452                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
   8453                 } else {
   8454                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
   8455                 }
   8456             }
   8457 
   8458             if ((multipass) &&
   8459                     (m_postprocessor.getPPChannelCount() > 1)
   8460                     && (!mParameters.getQuadraCfa())) {
   8461                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
   8462                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
   8463                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
   8464                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
   8465                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   8466             } else {
   8467                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   8468             }
   8469 
   8470             cam_dimension_t thumb_src_dim;
   8471             cam_dimension_t thumb_dst_dim;
   8472             mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
   8473             mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
   8474             if ((thumb_dst_dim.width != thumb_src_dim.width) ||
   8475                     (thumb_dst_dim.height != thumb_src_dim.height)) {
   8476                 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
   8477                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   8478                 }
   8479             }
   8480 
   8481             break;
   8482 
   8483         case 1:
   8484             //Configure feature mask for second pass of reprocessing
   8485             pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
   8486             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
   8487                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
   8488                 if (rotation == 0) {
   8489                     pp_config.rotation = ROTATE_0;
   8490                 } else if (rotation == 90) {
   8491                     pp_config.rotation = ROTATE_90;
   8492                 } else if (rotation == 180) {
   8493                     pp_config.rotation = ROTATE_180;
   8494                 } else if (rotation == 270) {
   8495                     pp_config.rotation = ROTATE_270;
   8496                 }
   8497             }
   8498             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
   8499                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
   8500                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
   8501                 } else {
   8502                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
   8503                 }
   8504             }
   8505             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
   8506             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
   8507             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_BYPASS;
   8508             break;
   8509 
   8510         case 2:
   8511             //Setting feature for Quadra CFA
   8512             pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
   8513             break;
   8514 
   8515     }
   8516 
   8517     LOGH("pproc feature mask set = %llx pass count = %d",
   8518         pp_config.feature_mask, curIndex);
   8519     return rc;
   8520 }
   8521 
   8522 /*===========================================================================
   8523  * FUNCTION   : addReprocChannel
   8524  *
   8525  * DESCRIPTION: add a reprocess channel that will do reprocess on frames
   8526  *              coming from input channel
   8527  *
   8528  * PARAMETERS :
   8529  *   @pInputChannel : ptr to input channel whose frames will be post-processed
   8530  *   @cur_channel_index : Current channel index in multipass
   8531  *
   8532  * RETURN     : Ptr to the newly created channel obj. NULL if failed.
   8533  *==========================================================================*/
   8534 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
   8535         QCameraChannel *pInputChannel, int8_t cur_channel_index)
   8536 {
   8537     int32_t rc = NO_ERROR;
   8538     QCameraReprocessChannel *pChannel = NULL;
   8539     uint32_t burst_cnt = mParameters.getNumOfSnapshots();
   8540     uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);
   8541 
   8542     if (pInputChannel == NULL) {
   8543         LOGE("input channel obj is NULL");
   8544         return NULL;
   8545     }
   8546 
   8547     pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
   8548     if (NULL == pChannel) {
   8549         LOGE("no mem for reprocess channel");
   8550         return NULL;
   8551     }
   8552 
   8553     // Capture channel, only need snapshot and postview streams start together
   8554     mm_camera_channel_attr_t attr;
   8555     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   8556     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   8557     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   8558     rc = pChannel->init(&attr,
   8559                         postproc_channel_cb_routine,
   8560                         this);
   8561     if (rc != NO_ERROR) {
   8562         LOGE("init reprocess channel failed, ret = %d", rc);
   8563         delete pChannel;
   8564         return NULL;
   8565     }
   8566 
   8567     // pp feature config
   8568     cam_pp_feature_config_t pp_config;
   8569     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
   8570 
   8571     rc = getPPConfig(pp_config, cur_channel_index,
   8572             ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
   8573     if (rc != NO_ERROR){
   8574         LOGE("Error while creating PP config");
   8575         delete pChannel;
   8576         return NULL;
   8577     }
   8578 
   8579     uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
   8580 
   8581     //WNR and HDR happen inline. No extra buffers needed.
   8582     cam_feature_mask_t temp_feature_mask = pp_config.feature_mask;
   8583     temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
   8584     if (temp_feature_mask && mParameters.isHDREnabled()) {
   8585         minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
   8586     }
   8587 
   8588     if (mParameters.isStillMoreEnabled()) {
   8589         cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
   8590         pp_config.burst_cnt = stillmore_config.burst_count;
   8591         LOGH("Stillmore burst %d", pp_config.burst_cnt);
   8592 
   8593         // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
   8594         // number of capture is already added. In the case of liveshot,
   8595         // stillmore burst is 1. This is to account for the premature decrement
   8596         if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
   8597             minStreamBufNum += 1;
   8598         }
   8599     }
   8600 
   8601     if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
   8602         minStreamBufNum += mParameters.getReprocCount() - 1;
   8603         burst_cnt = mParameters.getReprocCount();
   8604         if (cur_channel_index == 0) {
   8605             pChannel->setReprocCount(2);
   8606         } else {
   8607             pChannel->setReprocCount(1);
   8608         }
   8609     } else {
   8610         pChannel->setReprocCount(1);
   8611     }
   8612 
   8613     if (isDualCamera() && mBundledSnapshot) {
   8614         minStreamBufNum += 1;
   8615     }
   8616 
   8617     // Add non inplace image lib buffers only when ppproc is present,
   8618     // becuase pproc is non inplace and input buffers for img lib
   8619     // are output for pproc and this number of extra buffers is required
   8620     // If pproc is not there, input buffers for imglib are from snapshot stream
   8621     uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
   8622     if (temp_feature_mask && imglib_extra_bufs) {
   8623         // 1 is added because getNumOfExtraBuffersForImageProc returns extra
   8624         // buffers assuming number of capture is already added
   8625         minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
   8626     }
   8627 
   8628     //Mask out features that are already processed in snapshot stream.
   8629     cam_feature_mask_t snapshot_feature_mask = 0;
   8630     mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
   8631 
   8632     pp_config.feature_mask &= ~snapshot_feature_mask;
   8633     LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
   8634             snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);
   8635 
   8636     bool offlineReproc = needOfflineReprocessing();
   8637     if (m_postprocessor.mOfflineDataBufs != NULL) {
   8638         offlineReproc = TRUE;
   8639     }
   8640 
   8641     cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
   8642     paddingInfo.offset_info.offset_x = 0;
   8643     paddingInfo.offset_info.offset_y = 0;
   8644     rc = pChannel->addReprocStreamsFromSource(*this,
   8645                                               pp_config,
   8646                                               pInputChannel,
   8647                                               minStreamBufNum,
   8648                                               burst_cnt,
   8649                                               &paddingInfo,
   8650                                               mParameters,
   8651                                               mLongshotEnabled,
   8652                                               offlineReproc);
   8653     if (rc != NO_ERROR) {
   8654         delete pChannel;
   8655         return NULL;
   8656     }
   8657 
   8658     return pChannel;
   8659 }
   8660 
   8661 /*===========================================================================
   8662  * FUNCTION   : addOfflineReprocChannel
   8663  *
   8664  * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
   8665  *              that will do reprocess on frames coming from external images
   8666  *
   8667  * PARAMETERS :
   8668  *   @img_config  : offline reporcess image info
   8669  *   @pp_feature  : pp feature config
   8670  *
   8671  * RETURN     : int32_t type of status
   8672  *              NO_ERROR  -- success
   8673  *              none-zero failure code
   8674  *==========================================================================*/
   8675 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
   8676                                             cam_pp_offline_src_config_t &img_config,
   8677                                             cam_pp_feature_config_t &pp_feature,
   8678                                             stream_cb_routine stream_cb,
   8679                                             void *userdata)
   8680 {
   8681     int32_t rc = NO_ERROR;
   8682     QCameraReprocessChannel *pChannel = NULL;
   8683 
   8684     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
   8685                                            mCameraHandle->ops);
   8686     if (NULL == pChannel) {
   8687         LOGE("no mem for reprocess channel");
   8688         return NULL;
   8689     }
   8690 
   8691     rc = pChannel->init(NULL, NULL, NULL);
   8692     if (rc != NO_ERROR) {
   8693         LOGE("init reprocess channel failed, ret = %d", rc);
   8694         delete pChannel;
   8695         return NULL;
   8696     }
   8697 
   8698     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
   8699     if (pStreamInfo == NULL) {
   8700         LOGE("no mem for stream info buf");
   8701         delete pChannel;
   8702         return NULL;
   8703     }
   8704 
   8705     cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
   8706     memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
   8707     streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
   8708     streamInfoBuf->fmt = img_config.input_fmt;
   8709     streamInfoBuf->dim = img_config.input_dim;
   8710     streamInfoBuf->buf_planes = img_config.input_buf_planes;
   8711     streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
   8712     streamInfoBuf->num_of_burst = img_config.num_of_bufs;
   8713 
   8714     streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
   8715     streamInfoBuf->reprocess_config.offline = img_config;
   8716     streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
   8717     streamInfoBuf->num_bufs = img_config.num_of_bufs;
   8718 
   8719     rc = pChannel->addStream(*this,
   8720             pStreamInfo, NULL,
   8721             &gCamCapability[mCameraId]->padding_info,
   8722             stream_cb, userdata, false);
   8723 
   8724     if (rc != NO_ERROR) {
   8725         LOGE("add reprocess stream failed, ret = %d", rc);
   8726         delete pChannel;
   8727         return NULL;
   8728     }
   8729 
   8730     return pChannel;
   8731 }
   8732 
   8733 /*===========================================================================
   8734  * FUNCTION   : addChannel
   8735  *
   8736  * DESCRIPTION: add a channel by its type
   8737  *
   8738  * PARAMETERS :
   8739  *   @ch_type : channel type
   8740  *
   8741  * RETURN     : int32_t type of status
   8742  *              NO_ERROR  -- success
   8743  *              none-zero failure code
   8744  *==========================================================================*/
   8745 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
   8746 {
   8747     int32_t rc = UNKNOWN_ERROR;
   8748     switch (ch_type) {
   8749     case QCAMERA_CH_TYPE_ZSL:
   8750         rc = addZSLChannel();
   8751         break;
   8752     case QCAMERA_CH_TYPE_CAPTURE:
   8753         rc = addCaptureChannel();
   8754         break;
   8755     case QCAMERA_CH_TYPE_PREVIEW:
   8756         rc = addPreviewChannel();
   8757         break;
   8758     case QCAMERA_CH_TYPE_VIDEO:
   8759         rc = addVideoChannel();
   8760         break;
   8761     case QCAMERA_CH_TYPE_SNAPSHOT:
   8762         rc = addSnapshotChannel();
   8763         break;
   8764     case QCAMERA_CH_TYPE_RAW:
   8765         rc = addRawChannel();
   8766         break;
   8767     case QCAMERA_CH_TYPE_METADATA:
   8768         rc = addMetaDataChannel();
   8769         break;
   8770     case QCAMERA_CH_TYPE_CALLBACK:
   8771         rc = addCallbackChannel();
   8772         break;
   8773     case QCAMERA_CH_TYPE_ANALYSIS:
   8774         rc = addAnalysisChannel();
   8775         break;
   8776     default:
   8777         break;
   8778     }
   8779     return rc;
   8780 }
   8781 
   8782 /*===========================================================================
   8783  * FUNCTION   : delChannel
   8784  *
   8785  * DESCRIPTION: delete a channel by its type
   8786  *
   8787  * PARAMETERS :
   8788  *   @ch_type : channel type
   8789  *   @destroy : delete context as well
   8790  *
   8791  * RETURN     : int32_t type of status
   8792  *              NO_ERROR  -- success
   8793  *              none-zero failure code
   8794  *==========================================================================*/
   8795 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
   8796                                               bool destroy)
   8797 {
   8798     if (m_channels[ch_type] != NULL) {
   8799         if (destroy) {
   8800             delete m_channels[ch_type];
   8801             m_channels[ch_type] = NULL;
   8802         } else {
   8803             m_channels[ch_type]->deleteChannel();
   8804         }
   8805     }
   8806 
   8807     return NO_ERROR;
   8808 }
   8809 
   8810 /*===========================================================================
   8811  * FUNCTION   : startChannel
   8812  *
   8813  * DESCRIPTION: start a channel by its type
   8814  *
   8815  * PARAMETERS :
   8816  *   @ch_type : channel type
   8817  *
   8818  * RETURN     : int32_t type of status
   8819  *              NO_ERROR  -- success
   8820  *              none-zero failure code
   8821  *==========================================================================*/
   8822 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
   8823 {
   8824     int32_t rc = UNKNOWN_ERROR;
   8825     if (m_channels[ch_type] != NULL) {
   8826         rc = m_channels[ch_type]->start();
   8827     }
   8828     return rc;
   8829 }
   8830 
   8831 /*===========================================================================
   8832  * FUNCTION   : stopChannel
   8833  *
   8834  * DESCRIPTION: stop a channel by its type
   8835  *
   8836  * PARAMETERS :
   8837  *   @ch_type : channel type
   8838  *
   8839  * RETURN     : int32_t type of status
   8840  *              NO_ERROR  -- success
   8841  *              none-zero failure code
   8842  *==========================================================================*/
   8843 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
   8844 {
   8845     int32_t rc = UNKNOWN_ERROR;
   8846     if (m_channels[ch_type] != NULL) {
   8847         rc = m_channels[ch_type]->stop();
   8848     }
   8849 
   8850     return rc;
   8851 }
   8852 
   8853 /*===========================================================================
   8854  * FUNCTION   : preparePreview
   8855  *
   8856  * DESCRIPTION: add channels needed for preview
   8857  *
   8858  * PARAMETERS : none
   8859  *
   8860  * RETURN     : int32_t type of status
   8861  *              NO_ERROR  -- success
   8862  *              none-zero failure code
   8863  *==========================================================================*/
   8864 int32_t QCamera2HardwareInterface::preparePreview()
   8865 {
   8866     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPAREPREVIEW);
   8867     int32_t rc = NO_ERROR;
   8868 
   8869     LOGI("E");
   8870     rc = mParameters.setStreamConfigure(false, false, false);
   8871     if (rc != NO_ERROR) {
   8872         LOGE("setStreamConfigure failed %d", rc);
   8873         return rc;
   8874     }
   8875 
   8876     //Trigger deferred job second camera
   8877     if (isDualCamera()) {
   8878         mParameters.setDeferCamera(CAM_DEFER_START);
   8879     }
   8880 
   8881     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
   8882         rc = addChannel(QCAMERA_CH_TYPE_ZSL);
   8883         if (rc != NO_ERROR) {
   8884             LOGE("failed!! rc = %d", rc);
   8885             return rc;
   8886         }
   8887 
   8888         if (mParameters.isUBWCEnabled()) {
   8889             cam_format_t fmt;
   8890             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
   8891             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   8892                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
   8893                 if (rc != NO_ERROR) {
   8894                     delChannel(QCAMERA_CH_TYPE_ZSL);
   8895                     LOGE("failed!! rc = %d", rc);
   8896                     return rc;
   8897                 }
   8898             }
   8899         }
   8900 
   8901         if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) {
   8902             addChannel(QCAMERA_CH_TYPE_RAW);
   8903         }
   8904     } else if(isSecureMode()) {
   8905         if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
   8906             rc = addChannel(QCAMERA_CH_TYPE_RAW);
   8907         } else {
   8908             rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
   8909         }
   8910     } else {
   8911         bool recordingHint = mParameters.getRecordingHintValue();
   8912         if(!isRdiMode() && recordingHint) {
   8913             //stop face detection,longshot,etc if turned ON in Camera mode
   8914 #ifndef VANILLA_HAL
   8915             int32_t arg; //dummy arg
   8916             if (isLongshotEnabled()) {
   8917                 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
   8918             }
   8919             if (mParameters.isFaceDetectionEnabled()
   8920                     && (!mParameters.fdModeInVideo())) {
   8921                 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
   8922             }
   8923             if (mParameters.isHistogramEnabled()) {
   8924                 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
   8925             }
   8926 #endif
   8927             //Don't create snapshot channel for liveshot, if low power mode is set.
   8928             //Use video stream instead.
   8929             if (!isLowPowerMode()) {
   8930                rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8931                if (rc != NO_ERROR) {
   8932                    return rc;
   8933                }
   8934             }
   8935 
   8936             rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
   8937             if (rc != NO_ERROR) {
   8938                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8939                 LOGE("failed!! rc = %d", rc);
   8940                 return rc;
   8941             }
   8942         }
   8943 
   8944         rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
   8945         if (!isRdiMode() && (rc != NO_ERROR)) {
   8946             if (recordingHint) {
   8947                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8948                 delChannel(QCAMERA_CH_TYPE_VIDEO);
   8949             }
   8950         }
   8951 
   8952         if (mParameters.isUBWCEnabled() && !recordingHint) {
   8953             cam_format_t fmt;
   8954             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
   8955             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   8956                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
   8957                 if (rc != NO_ERROR) {
   8958                     delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8959                     if (!isRdiMode()) {
   8960                         delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8961                         delChannel(QCAMERA_CH_TYPE_VIDEO);
   8962                     }
   8963                     LOGE("failed!! rc = %d", rc);
   8964                     return rc;
   8965                 }
   8966             }
   8967         }
   8968 
   8969         if (NO_ERROR != rc) {
   8970             delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8971             LOGE("failed!! rc = %d", rc);
   8972         }
   8973     }
   8974 
   8975     if ((rc != NO_ERROR) && (isDualCamera())) {
   8976         mParameters.setDeferCamera(CAM_DEFER_FLUSH);
   8977     }
   8978 
   8979     LOGI("X rc = %d", rc);
   8980     return rc;
   8981 }
   8982 
   8983 /*===========================================================================
   8984  * FUNCTION   : unpreparePreview
   8985  *
   8986  * DESCRIPTION: delete channels for preview
   8987  *
   8988  * PARAMETERS : none
   8989  *
   8990  * RETURN     : none
   8991  *==========================================================================*/
   8992 void QCamera2HardwareInterface::unpreparePreview()
   8993 {
   8994     if (isDualCamera()) {
   8995         mParameters.setDeferCamera(CAM_DEFER_FLUSH);
   8996     }
   8997     delChannel(QCAMERA_CH_TYPE_ZSL);
   8998     delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8999     delChannel(QCAMERA_CH_TYPE_VIDEO);
   9000     delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   9001     delChannel(QCAMERA_CH_TYPE_CALLBACK);
   9002     delChannel(QCAMERA_CH_TYPE_RAW);
   9003 }
   9004 
   9005 /*===========================================================================
   9006  * FUNCTION   : playShutter
   9007  *
   9008  * DESCRIPTION: send request to play shutter sound
   9009  *
   9010  * PARAMETERS : none
   9011  *
   9012  * RETURN     : none
   9013  *==========================================================================*/
   9014 void QCamera2HardwareInterface::playShutter(){
   9015      if (mNotifyCb == NULL ||
   9016          msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
   9017          LOGD("shutter msg not enabled or NULL cb");
   9018          return;
   9019      }
   9020      LOGH("CAMERA_MSG_SHUTTER ");
   9021      qcamera_callback_argm_t cbArg;
   9022      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   9023      cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
   9024      cbArg.msg_type = CAMERA_MSG_SHUTTER;
   9025      cbArg.ext1 = 0;
   9026      cbArg.ext2 = false;
   9027      m_cbNotifier.notifyCallback(cbArg);
   9028 }
   9029 
   9030 /*===========================================================================
   9031  * FUNCTION   : getChannelByHandle
   9032  *
   9033  * DESCRIPTION: return a channel by its handle
   9034  *
   9035  * PARAMETERS :
   9036  *   @channelHandle : channel handle
   9037  *
   9038  * RETURN     : a channel obj if found, NULL if not found
   9039  *==========================================================================*/
   9040 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
   9041 {
   9042     for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   9043         if (m_channels[i] != NULL &&
   9044             (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
   9045             return m_channels[i];
   9046         }
   9047     }
   9048 
   9049     return NULL;
   9050 }
   9051 /*===========================================================================
   9052  * FUNCTION   : needPreviewFDCallback
   9053  *
   9054  * DESCRIPTION: decides if needPreviewFDCallback
   9055  *
   9056  * PARAMETERS :
   9057  *   @num_faces : number of faces
   9058  *
   9059  * RETURN     : bool type of status
   9060  *              true  -- success
   9061  *              fale -- failure code
   9062  *==========================================================================*/
   9063 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
   9064 {
   9065     if (num_faces == 0 && mNumPreviewFaces == 0) {
   9066         return false;
   9067     }
   9068 
   9069     return true;
   9070 }
   9071 
   9072 /*===========================================================================
   9073  * FUNCTION   : processFaceDetectionReuslt
   9074  *
   9075  * DESCRIPTION: process face detection reuslt
   9076  *
   9077  * PARAMETERS :
   9078  *   @faces_data : ptr to face processing result struct
   9079  *
   9080  * RETURN     : int32_t type of status
   9081  *              NO_ERROR  -- success
   9082  *              none-zero failure code
   9083  *==========================================================================*/
   9084 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
   9085 {
   9086     if (!mParameters.isFaceDetectionEnabled()) {
   9087         LOGH("FaceDetection not enabled, no ops here");
   9088         return NO_ERROR;
   9089     }
   9090 
   9091     qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
   9092     cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
   9093     if ((NULL == mDataCb) ||
   9094         (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
   9095         (!needPreviewFDCallback(detect_data->num_faces_detected))
   9096 #ifndef VANILLA_HAL
   9097         || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
   9098 #endif
   9099         ) {
   9100         LOGH("metadata msgtype not enabled, no ops here");
   9101         return NO_ERROR;
   9102     }
   9103 
   9104     if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
   9105         // Don't send callback to app if this is skipped by fd at backend
   9106         return NO_ERROR;
   9107     }
   9108 
   9109     cam_dimension_t display_dim;
   9110     mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
   9111     if (display_dim.width <= 0 || display_dim.height <= 0) {
   9112         LOGE("Invalid preview width or height (%d x %d)",
   9113                display_dim.width, display_dim.height);
   9114         return UNKNOWN_ERROR;
   9115     }
   9116 
   9117     // process face detection result
   9118     // need separate face detection in preview or snapshot type
   9119     size_t faceResultSize = 0;
   9120     size_t data_len = 0;
   9121     if(fd_type == QCAMERA_FD_PREVIEW){
   9122         //fd for preview frames
   9123         faceResultSize = sizeof(camera_frame_metadata_t);
   9124         faceResultSize += sizeof(camera_face_t) * MAX_ROI;
   9125     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
   9126 #ifndef VANILLA_HAL
   9127         // fd for snapshot frames
   9128         //check if face is detected in this frame
   9129         if(detect_data->num_faces_detected > 0){
   9130             data_len = sizeof(camera_frame_metadata_t) +
   9131                     sizeof(camera_face_t) * detect_data->num_faces_detected;
   9132         }else{
   9133             //no face
   9134             data_len = 0;
   9135         }
   9136 #endif
   9137         faceResultSize = 1 *sizeof(int)    //meta data type
   9138                        + 1 *sizeof(int)    // meta data len
   9139                        + data_len;         //data
   9140     }
   9141 
   9142     camera_memory_t *faceResultBuffer = mGetMemory(-1,
   9143                                                    faceResultSize,
   9144                                                    1,
   9145                                                    mCallbackCookie);
   9146     if ( NULL == faceResultBuffer ) {
   9147         LOGE("Not enough memory for face result data");
   9148         return NO_MEMORY;
   9149     }
   9150 
   9151     unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
   9152     memset(pFaceResult, 0, faceResultSize);
   9153     unsigned char *faceData = NULL;
   9154     if(fd_type == QCAMERA_FD_PREVIEW){
   9155         faceData = pFaceResult;
   9156         mNumPreviewFaces = detect_data->num_faces_detected;
   9157     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
   9158 #ifndef VANILLA_HAL
   9159         //need fill meta type and meta data len first
   9160         int *data_header = (int* )pFaceResult;
   9161         data_header[0] = CAMERA_META_DATA_FD;
   9162         data_header[1] = (int)data_len;
   9163 
   9164         if(data_len <= 0){
   9165             //if face is not valid or do not have face, return
   9166             qcamera_callback_argm_t cbArg;
   9167             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   9168             cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   9169             cbArg.msg_type = CAMERA_MSG_META_DATA;
   9170             cbArg.data = faceResultBuffer;
   9171             cbArg.user_data = faceResultBuffer;
   9172             cbArg.cookie = this;
   9173             cbArg.release_cb = releaseCameraMemory;
   9174             int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   9175             if (rc != NO_ERROR) {
   9176                 LOGE("fail sending notification");
   9177                 faceResultBuffer->release(faceResultBuffer);
   9178             }
   9179             return rc;
   9180         }
   9181 #endif
   9182         faceData = pFaceResult + 2 *sizeof(int); //skip two int length
   9183     }
   9184 
   9185     camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
   9186     camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
   9187 
   9188     roiData->number_of_faces = detect_data->num_faces_detected;
   9189     roiData->faces = faces;
   9190     LOGL("FD_DEBUG : Frame[%d] : number_of_faces=%d, display_dim=%d %d",
   9191             detect_data->frame_id, detect_data->num_faces_detected,
   9192             display_dim.width, display_dim.height);
   9193     if (roiData->number_of_faces > 0) {
   9194         for (int i = 0; i < roiData->number_of_faces; i++) {
   9195             faces[i].id = detect_data->faces[i].face_id;
   9196             faces[i].score = detect_data->faces[i].score;
   9197 
   9198             // left
   9199             faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
   9200                     detect_data->faces[i].face_boundary.left,
   9201                     display_dim.width, 2000, -1000);
   9202 
   9203             // top
   9204             faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
   9205                     detect_data->faces[i].face_boundary.top,
   9206                     display_dim.height, 2000, -1000);
   9207 
   9208             // right
   9209             faces[i].rect[2] = faces[i].rect[0] +
   9210                     MAP_TO_DRIVER_COORDINATE(
   9211                     detect_data->faces[i].face_boundary.width,
   9212                     display_dim.width, 2000, 0);
   9213 
   9214              // bottom
   9215             faces[i].rect[3] = faces[i].rect[1] +
   9216                     MAP_TO_DRIVER_COORDINATE(
   9217                     detect_data->faces[i].face_boundary.height,
   9218                     display_dim.height, 2000, 0);
   9219 
   9220             LOGL("FD_DEBUG : Frame[%d] : Face[%d] : id=%d, score=%d, "
   9221                     "CAM[left=%d, top=%d, w=%d, h=%d], "
   9222                     "APP[left=%d, top=%d, right=%d, bottom=%d] ",
   9223                     detect_data->frame_id, i, faces[i].id, faces[i].score,
   9224                     detect_data->faces[i].face_boundary.left,
   9225                     detect_data->faces[i].face_boundary.top,
   9226                     detect_data->faces[i].face_boundary.width,
   9227                     detect_data->faces[i].face_boundary.height,
   9228                     faces[i].rect[0], faces[i].rect[1],
   9229                     faces[i].rect[2], faces[i].rect[3]);
   9230 
   9231             if (faces_data->landmark_valid) {
   9232                 // Center of left eye
   9233                 if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) {
   9234                     faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
   9235                             faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
   9236                             display_dim.width, 2000, -1000);
   9237                     faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
   9238                             faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
   9239                             display_dim.height, 2000, -1000);
   9240                 } else {
   9241                     faces[i].left_eye[0] = FACE_INVALID_POINT;
   9242                     faces[i].left_eye[1] = FACE_INVALID_POINT;
   9243                 }
   9244 
   9245                 // Center of right eye
   9246                 if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) {
   9247                     faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
   9248                             faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
   9249                             display_dim.width, 2000, -1000);
   9250                     faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
   9251                             faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
   9252                             display_dim.height, 2000, -1000);
   9253                 } else {
   9254                     faces[i].right_eye[0] = FACE_INVALID_POINT;
   9255                     faces[i].right_eye[1] = FACE_INVALID_POINT;
   9256                 }
   9257 
   9258                 // Center of mouth
   9259                 if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) {
   9260                     faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
   9261                             faces_data->landmark_data.face_landmarks[i].mouth_center.x,
   9262                             display_dim.width, 2000, -1000);
   9263                     faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
   9264                             faces_data->landmark_data.face_landmarks[i].mouth_center.y,
   9265                             display_dim.height, 2000, -1000);
   9266                 } else {
   9267                     faces[i].mouth[0] = FACE_INVALID_POINT;
   9268                     faces[i].mouth[1] = FACE_INVALID_POINT;
   9269                 }
   9270 
   9271                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
   9272                         "eye : left(%d, %d) right(%d, %d), mouth(%d, %d)",
   9273                         detect_data->frame_id, i, faces[i].left_eye[0], faces[i].left_eye[1],
   9274                         faces[i].right_eye[0], faces[i].right_eye[1],
   9275                         faces[i].mouth[0], faces[i].mouth[1]);
   9276             } else {
   9277                 // return -2000 if invalid
   9278                 faces[i].left_eye[0] = FACE_INVALID_POINT;
   9279                 faces[i].left_eye[1] = FACE_INVALID_POINT;
   9280 
   9281                 faces[i].right_eye[0] = FACE_INVALID_POINT;
   9282                 faces[i].right_eye[1] = FACE_INVALID_POINT;
   9283 
   9284                 faces[i].mouth[0] = FACE_INVALID_POINT;
   9285                 faces[i].mouth[1] = FACE_INVALID_POINT;
   9286             }
   9287 
   9288 #ifndef VANILLA_HAL
   9289 #ifdef TARGET_TS_MAKEUP
   9290             mFaceRect.left = detect_data->faces[i].face_boundary.left;
   9291             mFaceRect.top = detect_data->faces[i].face_boundary.top;
   9292             mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
   9293             mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
   9294 #endif
   9295             if (faces_data->smile_valid) {
   9296                 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
   9297                 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
   9298 
   9299                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : smile_degree=%d, smile_score=%d",
   9300                         detect_data->frame_id, i, faces[i].smile_degree, faces[i].smile_score);
   9301             }
   9302             if (faces_data->blink_valid) {
   9303                 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
   9304                 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
   9305                 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
   9306 
   9307                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
   9308                         "blink_detected=%d, leye_blink=%d, reye_blink=%d",
   9309                         detect_data->frame_id, i, faces[i].blink_detected, faces[i].leye_blink,
   9310                         faces[i].reye_blink);
   9311             }
   9312             if (faces_data->recog_valid) {
   9313                 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
   9314 
   9315                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : face_recognised=%d",
   9316                         detect_data->frame_id, i, faces[i].face_recognised);
   9317             }
   9318             if (faces_data->gaze_valid) {
   9319                 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
   9320                 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
   9321                 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
   9322                 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
   9323                 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
   9324                 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
   9325 
   9326                 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : gaze_angle=%d, updown_dir=%d, "
   9327                         "leftright_dir=%d,, roll_dir=%d, left_right_gaze=%d, top_bottom_gaze=%d",
   9328                         detect_data->frame_id, i, faces[i].gaze_angle, faces[i].updown_dir,
   9329                         faces[i].leftright_dir, faces[i].roll_dir, faces[i].left_right_gaze,
   9330                         faces[i].top_bottom_gaze);
   9331             }
   9332 #endif
   9333 
   9334         }
   9335     }
   9336     else{
   9337 #ifdef TARGET_TS_MAKEUP
   9338         memset(&mFaceRect,-1,sizeof(mFaceRect));
   9339 #endif
   9340     }
   9341     qcamera_callback_argm_t cbArg;
   9342     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   9343     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   9344     if(fd_type == QCAMERA_FD_PREVIEW){
   9345         cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
   9346     }
   9347 #ifndef VANILLA_HAL
   9348     else if(fd_type == QCAMERA_FD_SNAPSHOT){
   9349         cbArg.msg_type = CAMERA_MSG_META_DATA;
   9350     }
   9351 #endif
   9352     cbArg.data = faceResultBuffer;
   9353     cbArg.metadata = roiData;
   9354     cbArg.user_data = faceResultBuffer;
   9355     cbArg.cookie = this;
   9356     cbArg.release_cb = releaseCameraMemory;
   9357     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   9358     if (rc != NO_ERROR) {
   9359         LOGE("fail sending notification");
   9360         faceResultBuffer->release(faceResultBuffer);
   9361     }
   9362 
   9363     return rc;
   9364 }
   9365 
   9366 /*===========================================================================
   9367  * FUNCTION   : releaseCameraMemory
   9368  *
   9369  * DESCRIPTION: releases camera memory objects
   9370  *
   9371  * PARAMETERS :
   9372  *   @data    : buffer to be released
   9373  *   @cookie  : context data
   9374  *   @cbStatus: callback status
   9375  *
   9376  * RETURN     : None
   9377  *==========================================================================*/
   9378 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
   9379                                                     void */*cookie*/,
   9380                                                     int32_t /*cbStatus*/)
   9381 {
   9382     camera_memory_t *mem = ( camera_memory_t * ) data;
   9383     if ( NULL != mem ) {
   9384         mem->release(mem);
   9385     }
   9386 }
   9387 
   9388 /*===========================================================================
   9389  * FUNCTION   : returnStreamBuffer
   9390  *
   9391  * DESCRIPTION: returns back a stream buffer
   9392  *
   9393  * PARAMETERS :
   9394  *   @data    : buffer to be released
   9395  *   @cookie  : context data
   9396  *   @cbStatus: callback status
   9397  *
   9398  * RETURN     : None
   9399  *==========================================================================*/
   9400 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
   9401                                                    void *cookie,
   9402                                                    int32_t /*cbStatus*/)
   9403 {
   9404     QCameraStream *stream = ( QCameraStream * ) cookie;
   9405     int idx = *((int *)data);
   9406     if ((NULL != stream) && (0 <= idx)) {
   9407         stream->bufDone((uint32_t)idx);
   9408     } else {
   9409         LOGE("Cannot return buffer %d %p", idx, cookie);
   9410     }
   9411 }
   9412 
   9413 /*===========================================================================
   9414  * FUNCTION   : processHistogramStats
   9415  *
   9416  * DESCRIPTION: process histogram stats
   9417  *
   9418  * PARAMETERS :
   9419  *   @hist_data : ptr to histogram stats struct
   9420  *
   9421  * RETURN     : int32_t type of status
   9422  *              NO_ERROR  -- success
   9423  *              none-zero failure code
   9424  *==========================================================================*/
   9425 int32_t QCamera2HardwareInterface::processHistogramStats(
   9426         __unused cam_hist_stats_t &stats_data)
   9427 {
   9428 #ifndef VANILLA_HAL
   9429     if (!mParameters.isHistogramEnabled()) {
   9430         LOGH("Histogram not enabled, no ops here");
   9431         return NO_ERROR;
   9432     }
   9433 
   9434     camera_memory_t *histBuffer = mGetMemory(-1,
   9435                                              sizeof(cam_histogram_data_t),
   9436                                              1,
   9437                                              mCallbackCookie);
   9438     if ( NULL == histBuffer ) {
   9439         LOGE("Not enough memory for histogram data");
   9440         return NO_MEMORY;
   9441     }
   9442 
   9443     cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
   9444     if (pHistData == NULL) {
   9445         LOGE("memory data ptr is NULL");
   9446         return UNKNOWN_ERROR;
   9447     }
   9448 
   9449     switch (stats_data.type) {
   9450     case CAM_HISTOGRAM_TYPE_BAYER:
   9451         switch (stats_data.bayer_stats.data_type) {
   9452             case CAM_STATS_CHANNEL_Y:
   9453             case CAM_STATS_CHANNEL_R:
   9454                 *pHistData = stats_data.bayer_stats.r_stats;
   9455                 break;
   9456             case CAM_STATS_CHANNEL_GR:
   9457                 *pHistData = stats_data.bayer_stats.gr_stats;
   9458                 break;
   9459             case CAM_STATS_CHANNEL_GB:
   9460             case CAM_STATS_CHANNEL_ALL:
   9461                 *pHistData = stats_data.bayer_stats.gb_stats;
   9462                 break;
   9463             case CAM_STATS_CHANNEL_B:
   9464                 *pHistData = stats_data.bayer_stats.b_stats;
   9465                 break;
   9466             default:
   9467                 *pHistData = stats_data.bayer_stats.r_stats;
   9468                 break;
   9469         }
   9470         break;
   9471     case CAM_HISTOGRAM_TYPE_YUV:
   9472         *pHistData = stats_data.yuv_stats;
   9473         break;
   9474     }
   9475 
   9476     qcamera_callback_argm_t cbArg;
   9477     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   9478     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   9479     cbArg.msg_type = CAMERA_MSG_STATS_DATA;
   9480     cbArg.data = histBuffer;
   9481     cbArg.user_data = histBuffer;
   9482     cbArg.cookie = this;
   9483     cbArg.release_cb = releaseCameraMemory;
   9484     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   9485     if (rc != NO_ERROR) {
   9486         LOGE("fail sending notification");
   9487         histBuffer->release(histBuffer);
   9488     }
   9489 #endif
   9490     return NO_ERROR;
   9491 }
   9492 
   9493 /*===========================================================================
   9494  * FUNCTION   : calcThermalLevel
   9495  *
   9496  * DESCRIPTION: Calculates the target fps range depending on
   9497  *              the thermal level.
   9498  *              Note that this function can be called from QCameraParametersIntf
   9499  *              while mutex is held. So it should not call back into
   9500  *              QCameraParametersIntf causing deadlock.
   9501  *
   9502  * PARAMETERS :
   9503  *   @level      : received thermal level
   9504  *   @minFPS     : minimum configured fps range
   9505  *   @maxFPS     : maximum configured fps range
   9506  *   @minVideoFps: minimum configured fps range
   9507  *   @maxVideoFps: maximum configured fps range
   9508  *   @adjustedRange : target fps range
   9509  *   @skipPattern : target skip pattern
   9510  *   @bRecordingHint : recording hint value
   9511  *
   9512  * RETURN     : int32_t type of status
   9513  *              NO_ERROR  -- success
   9514  *              none-zero failure code
   9515  *==========================================================================*/
   9516 int QCamera2HardwareInterface::calcThermalLevel(
   9517             qcamera_thermal_level_enum_t level,
   9518             const int minFPSi,
   9519             const int maxFPSi,
   9520             const float &minVideoFps,
   9521             const float &maxVideoFps,
   9522             cam_fps_range_t &adjustedRange,
   9523             enum msm_vfe_frame_skip_pattern &skipPattern,
   9524             bool bRecordingHint)
   9525 {
   9526     const float minFPS = (float)minFPSi;
   9527     const float maxFPS = (float)maxFPSi;
   9528 
   9529     LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
   9530               "video minfps %f, video maxfpS %f",
   9531              level, minFPS, maxFPS, minVideoFps, maxVideoFps);
   9532 
   9533     switch(level) {
   9534     case QCAMERA_THERMAL_NO_ADJUSTMENT:
   9535         {
   9536             adjustedRange.min_fps = minFPS / 1000.0f;
   9537             adjustedRange.max_fps = maxFPS / 1000.0f;
   9538             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   9539             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   9540             skipPattern = NO_SKIP;
   9541         }
   9542         break;
   9543     case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
   9544         {
   9545             adjustedRange.min_fps = minFPS / 1000.0f;
   9546             adjustedRange.max_fps = maxFPS / 1000.0f;
   9547             adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
   9548             adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
   9549             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   9550             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   9551             adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
   9552             adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
   9553             if ( adjustedRange.min_fps < 1 ) {
   9554                 adjustedRange.min_fps = 1;
   9555             }
   9556             if ( adjustedRange.max_fps < 1 ) {
   9557                 adjustedRange.max_fps = 1;
   9558             }
   9559             if ( adjustedRange.video_min_fps < 1 ) {
   9560                 adjustedRange.video_min_fps = 1;
   9561             }
   9562             if ( adjustedRange.video_max_fps < 1 ) {
   9563                 adjustedRange.video_max_fps = 1;
   9564             }
   9565             skipPattern = EVERY_2FRAME;
   9566         }
   9567         break;
   9568     case QCAMERA_THERMAL_BIG_ADJUSTMENT:
   9569         {
   9570             adjustedRange.min_fps = minFPS / 1000.0f;
   9571             adjustedRange.max_fps = maxFPS / 1000.0f;
   9572             adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
   9573             adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
   9574             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   9575             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   9576             adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
   9577             adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
   9578             if ( adjustedRange.min_fps < 1 ) {
   9579                 adjustedRange.min_fps = 1;
   9580             }
   9581             if ( adjustedRange.max_fps < 1 ) {
   9582                 adjustedRange.max_fps = 1;
   9583             }
   9584             if ( adjustedRange.video_min_fps < 1 ) {
   9585                 adjustedRange.video_min_fps = 1;
   9586             }
   9587             if ( adjustedRange.video_max_fps < 1 ) {
   9588                 adjustedRange.video_max_fps = 1;
   9589             }
   9590             skipPattern = EVERY_4FRAME;
   9591         }
   9592         break;
   9593     case QCAMERA_THERMAL_MAX_ADJUSTMENT:
   9594         {
   9595             // Stop Preview?
   9596             // Set lowest min FPS for now
   9597             adjustedRange.min_fps = minFPS/1000.0f;
   9598             adjustedRange.max_fps = minFPS/1000.0f;
   9599             cam_capability_t *capability = gCamCapability[mCameraId];
   9600             for (size_t i = 0;
   9601                      i < capability->fps_ranges_tbl_cnt;
   9602                      i++) {
   9603                 if (capability->fps_ranges_tbl[i].min_fps <
   9604                         adjustedRange.min_fps) {
   9605                     adjustedRange.min_fps =
   9606                             capability->fps_ranges_tbl[i].min_fps;
   9607                     adjustedRange.max_fps = adjustedRange.min_fps;
   9608                 }
   9609             }
   9610             skipPattern = MAX_SKIP;
   9611             adjustedRange.video_min_fps = adjustedRange.min_fps;
   9612             adjustedRange.video_max_fps = adjustedRange.max_fps;
   9613         }
   9614         break;
   9615     case QCAMERA_THERMAL_SHUTDOWN:
   9616         {
   9617             // send error notify
   9618             LOGE("Received shutdown thermal level. Closing camera");
   9619             sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
   9620         }
   9621         break;
   9622     default:
   9623         {
   9624             LOGW("Invalid thermal level %d", level);
   9625             return BAD_VALUE;
   9626         }
   9627         break;
   9628     }
   9629     if (level >= QCAMERA_THERMAL_NO_ADJUSTMENT && level <= QCAMERA_THERMAL_MAX_ADJUSTMENT) {
   9630         if (bRecordingHint) {
   9631             adjustedRange.min_fps = minFPS / 1000.0f;
   9632             adjustedRange.max_fps = maxFPS / 1000.0f;
   9633             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   9634             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   9635             skipPattern = NO_SKIP;
   9636             LOGH("No FPS mitigation in camcorder mode");
   9637         }
   9638         LOGH("Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
   9639                   level, adjustedRange.min_fps, adjustedRange.max_fps,
   9640                     adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
   9641     }
   9642 
   9643     return NO_ERROR;
   9644 }
   9645 
   9646 /*===========================================================================
   9647  * FUNCTION   : recalcFPSRange
   9648  *
   9649  * DESCRIPTION: adjust the configured fps range regarding
   9650  *              the last thermal level.
   9651  *
   9652  * PARAMETERS :
   9653  *   @minFPS      : minimum configured fps range
   9654  *   @maxFPS      : maximum configured fps range
   9655  *   @minVideoFPS : minimum configured video fps
   9656  *   @maxVideoFPS : maximum configured video fps
   9657  *   @adjustedRange : target fps range
   9658  *   @bRecordingHint : recording hint value
   9659  *
   9660  * RETURN     : int32_t type of status
   9661  *              NO_ERROR  -- success
   9662  *              none-zero failure code
   9663  *==========================================================================*/
   9664 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
   9665         const float &minVideoFPS, const float &maxVideoFPS,
   9666         cam_fps_range_t &adjustedRange, bool bRecordingHint)
   9667 {
   9668     enum msm_vfe_frame_skip_pattern skipPattern;
   9669     calcThermalLevel(mThermalLevel,
   9670                      minFPS,
   9671                      maxFPS,
   9672                      minVideoFPS,
   9673                      maxVideoFPS,
   9674                      adjustedRange,
   9675                      skipPattern,
   9676                      bRecordingHint);
   9677     return NO_ERROR;
   9678 }
   9679 
   9680 /*===========================================================================
   9681  * FUNCTION   : updateThermalLevel
   9682  *
   9683  * DESCRIPTION: update thermal level depending on thermal events
   9684  *
   9685  * PARAMETERS :
   9686  *   @level   : thermal level
   9687  *
   9688  * RETURN     : int32_t type of status
   9689  *              NO_ERROR  -- success
   9690  *              none-zero failure code
   9691  *==========================================================================*/
   9692 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
   9693 {
   9694     int ret = NO_ERROR;
   9695     cam_fps_range_t adjustedRange;
   9696     int minFPS, maxFPS;
   9697     float minVideoFPS, maxVideoFPS;
   9698     enum msm_vfe_frame_skip_pattern skipPattern;
   9699     bool value;
   9700     qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
   9701 
   9702 
   9703     if (!mCameraOpened) {
   9704         LOGH("Camera is not opened, no need to update camera parameters");
   9705         return NO_ERROR;
   9706     }
   9707 
   9708     mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   9709     qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
   9710     if (mParameters.isHfrMode()) {
   9711         cam_fps_range_t hfrFpsRange;
   9712         mParameters.getHfrFps(hfrFpsRange);
   9713         minVideoFPS = hfrFpsRange.video_min_fps;
   9714         maxVideoFPS = hfrFpsRange.video_max_fps;
   9715     } else {
   9716         minVideoFPS = minFPS;
   9717         maxVideoFPS = maxFPS;
   9718     }
   9719 
   9720     value = mParameters.getRecordingHintValue();
   9721     calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
   9722             adjustedRange, skipPattern, value );
   9723     mThermalLevel = level;
   9724 
   9725     if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
   9726         ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
   9727     else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
   9728         ret = mParameters.setFrameSkip(skipPattern);
   9729     else
   9730         LOGW("Incorrect thermal mode %d", thermalMode);
   9731 
   9732     return ret;
   9733 
   9734 }
   9735 
   9736 /*===========================================================================
   9737  * FUNCTION   : updateParameters
   9738  *
   9739  * DESCRIPTION: update parameters
   9740  *
   9741  * PARAMETERS :
   9742  *   @parms       : input parameters string
   9743  *   @needRestart : output, flag to indicate if preview restart is needed
   9744  *
   9745  * RETURN     : int32_t type of status
   9746  *              NO_ERROR  -- success
   9747  *              none-zero failure code
   9748  *==========================================================================*/
   9749 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
   9750 {
   9751     int rc = NO_ERROR;
   9752 
   9753     String8 str = String8(parms);
   9754     rc =  mParameters.updateParameters(str, needRestart);
   9755     setNeedRestart(needRestart);
   9756 
   9757     // update stream based parameter settings
   9758     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   9759         if (m_channels[i] != NULL) {
   9760             m_channels[i]->UpdateStreamBasedParameters(mParameters);
   9761         }
   9762     }
   9763 
   9764     return rc;
   9765 }
   9766 
   9767 /*===========================================================================
   9768  * FUNCTION   : commitParameterChanges
   9769  *
   9770  * DESCRIPTION: commit parameter changes to the backend to take effect
   9771  *
   9772  * PARAMETERS : none
   9773  *
   9774  * RETURN     : int32_t type of status
   9775  *              NO_ERROR  -- success
   9776  *              none-zero failure code
   9777  * NOTE       : This function must be called after updateParameters.
   9778  *              Otherwise, no change will be passed to backend to take effect.
   9779  *==========================================================================*/
   9780 int QCamera2HardwareInterface::commitParameterChanges()
   9781 {
   9782     int rc = NO_ERROR;
   9783     rc = mParameters.commitParameters();
   9784     if (rc == NO_ERROR) {
   9785         // update number of snapshot based on committed parameters setting
   9786         rc = mParameters.setNumOfSnapshot();
   9787     }
   9788 
   9789     if (isDualCamera() &&
   9790         mParameters.isZoomChanged()) {
   9791         // If zoom changes, get the updated FOV-control result and if needed send the dual
   9792         // camera parameters to backend
   9793         processDualCamFovControl();
   9794     }
   9795     return rc;
   9796 }
   9797 
   9798 /*===========================================================================
   9799  * FUNCTION   : needDebugFps
   9800  *
   9801  * DESCRIPTION: if fps log info need to be printed out
   9802  *
   9803  * PARAMETERS : none
   9804  *
   9805  * RETURN     : true: need print out fps log
   9806  *              false: no need to print out fps log
   9807  *==========================================================================*/
   9808 bool QCamera2HardwareInterface::needDebugFps()
   9809 {
   9810     bool needFps = false;
   9811     needFps = mParameters.isFpsDebugEnabled();
   9812     return needFps;
   9813 }
   9814 
   9815 /*===========================================================================
   9816  * FUNCTION   : isCACEnabled
   9817  *
   9818  * DESCRIPTION: if CAC is enabled
   9819  *
   9820  * PARAMETERS : none
   9821  *
   9822  * RETURN     : true: needed
   9823  *              false: no need
   9824  *==========================================================================*/
   9825 bool QCamera2HardwareInterface::isCACEnabled()
   9826 {
   9827     char prop[PROPERTY_VALUE_MAX];
   9828     memset(prop, 0, sizeof(prop));
   9829     property_get("persist.camera.feature.cac", prop, "0");
   9830     int enableCAC = atoi(prop);
   9831     return enableCAC == 1;
   9832 }
   9833 
   9834 /*===========================================================================
   9835  * FUNCTION   : is4k2kResolution
   9836  *
   9837  * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
   9838  *
   9839  * PARAMETERS : none
   9840  *
   9841  * RETURN     : true: needed
   9842  *              false: no need
   9843  *==========================================================================*/
   9844 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
   9845 {
   9846    bool enabled = false;
   9847    if ((resolution->width == 4096 && resolution->height == 2160) ||
   9848        (resolution->width == 3840 && resolution->height == 2160) ) {
   9849       enabled = true;
   9850    }
   9851    return enabled;
   9852 }
   9853 
   9854 /*===========================================================================
   9855  * FUNCTION   : isPreviewRestartEnabled
   9856  *
   9857  * DESCRIPTION: Check whether preview should be restarted automatically
   9858  *              during image capture.
   9859  *
   9860  * PARAMETERS : none
   9861  *
   9862  * RETURN     : true: needed
   9863  *              false: no need
   9864  *==========================================================================*/
   9865 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
   9866 {
   9867     char prop[PROPERTY_VALUE_MAX];
   9868     memset(prop, 0, sizeof(prop));
   9869     property_get("persist.camera.feature.restart", prop, "0");
   9870     int earlyRestart = atoi(prop);
   9871     return earlyRestart == 1;
   9872 }
   9873 
   9874 /*===========================================================================
   9875  * FUNCTION   : needReprocess
   9876  *
   9877  * DESCRIPTION: if reprocess is needed
   9878  *
   9879  * PARAMETERS : none
   9880  *
   9881  * RETURN     : true: needed
   9882  *              false: no need
   9883  *==========================================================================*/
   9884 bool QCamera2HardwareInterface::needReprocess()
   9885 {
   9886     bool needReprocess = false;
   9887 
   9888     if (!mParameters.isJpegPictureFormat() &&
   9889         !mParameters.isNV21PictureFormat()) {
   9890         // RAW image, no need to reprocess
   9891         return false;
   9892     }
   9893 
   9894     //Disable reprocess for small jpeg size or 4K liveshot case but enable if lowpower mode
   9895     if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
   9896             && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
   9897         return false;
   9898     }
   9899 
   9900     // pp feature config
   9901     cam_pp_feature_config_t pp_config;
   9902     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
   9903 
   9904     //Decide whether to do reprocess or not based on
   9905     //ppconfig obtained in the first pass.
   9906     getPPConfig(pp_config);
   9907 
   9908     if (pp_config.feature_mask > 0) {
   9909         needReprocess = true;
   9910     }
   9911 
   9912     LOGH("needReprocess %s", needReprocess ? "true" : "false");
   9913     return needReprocess;
   9914 }
   9915 
   9916 
   9917 /*===========================================================================
   9918  * FUNCTION   : needRotationReprocess
   9919  *
   9920  * DESCRIPTION: if rotation needs to be done by reprocess in pp
   9921  *
   9922  * PARAMETERS : none
   9923  *
   9924  * RETURN     : true: needed
   9925  *              false: no need
   9926  *==========================================================================*/
   9927 bool QCamera2HardwareInterface::needRotationReprocess()
   9928 {
   9929     if (!mParameters.isJpegPictureFormat() &&
   9930         !mParameters.isNV21PictureFormat()) {
   9931         // RAW image, no need to reprocess
   9932         return false;
   9933     }
   9934 
   9935     //Disable reprocess for 4K liveshot case
   9936     if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
   9937             && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
   9938         //Disable reprocess for 4K liveshot case or small jpeg size
   9939          return false;
   9940     }
   9941 
   9942     if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
   9943             CAM_QCOM_FEATURE_ROTATION) > 0 &&
   9944             (mParameters.getJpegRotation() > 0)) {
   9945         // current rotation is not zero, and pp has the capability to process rotation
   9946         LOGH("need to do reprocess for rotation=%d",
   9947                  mParameters.getJpegRotation());
   9948         return true;
   9949     }
   9950 
   9951     return false;
   9952 }
   9953 
   9954 /*===========================================================================
   9955  * FUNCTION   : getThumbnailSize
   9956  *
   9957  * DESCRIPTION: get user set thumbnail size
   9958  *
   9959  * PARAMETERS :
   9960  *   @dim     : output of thumbnail dimension
   9961  *
   9962  * RETURN     : none
   9963  *==========================================================================*/
   9964 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
   9965 {
   9966     mParameters.getThumbnailSize(&dim.width, &dim.height);
   9967 }
   9968 
   9969 /*===========================================================================
   9970  * FUNCTION   : getJpegQuality
   9971  *
   9972  * DESCRIPTION: get user set jpeg quality
   9973  *
   9974  * PARAMETERS : none
   9975  *
   9976  * RETURN     : jpeg quality setting
   9977  *==========================================================================*/
   9978 uint32_t QCamera2HardwareInterface::getJpegQuality()
   9979 {
   9980     uint32_t quality = 0;
   9981     quality =  mParameters.getJpegQuality();
   9982     return quality;
   9983 }
   9984 
   9985 /*===========================================================================
   9986  * FUNCTION   : getExifData
   9987  *
   9988  * DESCRIPTION: get exif data to be passed into jpeg encoding
   9989  *
   9990  * PARAMETERS : none
   9991  *
   9992  * RETURN     : exif data from user setting and GPS
   9993  *==========================================================================*/
   9994 QCameraExif *QCamera2HardwareInterface::getExifData()
   9995 {
   9996     QCameraExif *exif = new QCameraExif();
   9997     if (exif == NULL) {
   9998         LOGE("No memory for QCameraExif");
   9999         return NULL;
   10000     }
   10001 
   10002     int32_t rc = NO_ERROR;
   10003 
   10004     // add exif entries
   10005     String8 dateTime, subSecTime;
   10006     rc = mParameters.getExifDateTime(dateTime, subSecTime);
   10007     if(rc == NO_ERROR) {
   10008         exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
   10009                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   10010         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
   10011                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   10012         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
   10013                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   10014         exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
   10015                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   10016         exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
   10017                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   10018         exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
   10019                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   10020     } else {
   10021         LOGW("getExifDateTime failed");
   10022     }
   10023 
   10024     rat_t focalLength;
   10025     rc = mParameters.getExifFocalLength(&focalLength);
   10026     if (rc == NO_ERROR) {
   10027         exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
   10028                        EXIF_RATIONAL,
   10029                        1,
   10030                        (void *)&(focalLength));
   10031     } else {
   10032         LOGW("getExifFocalLength failed");
   10033     }
   10034 
   10035     uint16_t isoSpeed = mParameters.getExifIsoSpeed();
   10036     if (getSensorType() != CAM_SENSOR_YUV) {
   10037         exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
   10038                        EXIF_SHORT,
   10039                        1,
   10040                        (void *)&(isoSpeed));
   10041     }
   10042 
   10043     char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
   10044     uint32_t count = 0;
   10045 
   10046     /*gps data might not be available */
   10047     rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
   10048     if(rc == NO_ERROR) {
   10049         exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
   10050                        EXIF_ASCII,
   10051                        count,
   10052                        (void *)gpsProcessingMethod);
   10053     } else {
   10054         LOGW("getExifGpsProcessingMethod failed");
   10055     }
   10056 
   10057     rat_t latitude[3];
   10058     char latRef[2];
   10059     rc = mParameters.getExifLatitude(latitude, latRef);
   10060     if(rc == NO_ERROR) {
   10061         exif->addEntry(EXIFTAGID_GPS_LATITUDE,
   10062                        EXIF_RATIONAL,
   10063                        3,
   10064                        (void *)latitude);
   10065         exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
   10066                        EXIF_ASCII,
   10067                        2,
   10068                        (void *)latRef);
   10069     } else {
   10070         LOGW("getExifLatitude failed");
   10071     }
   10072 
   10073     rat_t longitude[3];
   10074     char lonRef[2];
   10075     rc = mParameters.getExifLongitude(longitude, lonRef);
   10076     if(rc == NO_ERROR) {
   10077         exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
   10078                        EXIF_RATIONAL,
   10079                        3,
   10080                        (void *)longitude);
   10081 
   10082         exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
   10083                        EXIF_ASCII,
   10084                        2,
   10085                        (void *)lonRef);
   10086     } else {
   10087         LOGW("getExifLongitude failed");
   10088     }
   10089 
   10090     rat_t altitude;
   10091     char altRef;
   10092     rc = mParameters.getExifAltitude(&altitude, &altRef);
   10093     if(rc == NO_ERROR) {
   10094         exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
   10095                        EXIF_RATIONAL,
   10096                        1,
   10097                        (void *)&(altitude));
   10098 
   10099         exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
   10100                        EXIF_BYTE,
   10101                        1,
   10102                        (void *)&altRef);
   10103     } else {
   10104         LOGW("getExifAltitude failed");
   10105     }
   10106 
   10107     char gpsDateStamp[20];
   10108     rat_t gpsTimeStamp[3];
   10109     rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
   10110     if(rc == NO_ERROR) {
   10111         exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
   10112                        EXIF_ASCII,
   10113                        (uint32_t)(strlen(gpsDateStamp) + 1),
   10114                        (void *)gpsDateStamp);
   10115 
   10116         exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
   10117                        EXIF_RATIONAL,
   10118                        3,
   10119                        (void *)gpsTimeStamp);
   10120     } else {
   10121         LOGW("getExifGpsDataTimeStamp failed");
   10122     }
   10123 
   10124 #ifdef ENABLE_MODEL_INFO_EXIF
   10125 
   10126     char value[PROPERTY_VALUE_MAX];
   10127     if (property_get("persist.sys.exif.make", value, "") > 0 ||
   10128             property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
   10129         exif->addEntry(EXIFTAGID_MAKE,
   10130                 EXIF_ASCII, strlen(value) + 1, (void *)value);
   10131     } else {
   10132         LOGW("getExifMaker failed");
   10133     }
   10134 
   10135     if (property_get("persist.sys.exif.model", value, "") > 0 ||
   10136             property_get("ro.product.model", value, "QCAM-AA") > 0) {
   10137         exif->addEntry(EXIFTAGID_MODEL,
   10138                 EXIF_ASCII, strlen(value) + 1, (void *)value);
   10139     } else {
   10140         LOGW("getExifModel failed");
   10141     }
   10142 
   10143     if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
   10144         exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
   10145                 (uint32_t)(strlen(value) + 1), (void *)value);
   10146     } else {
   10147         LOGW("getExifSoftware failed");
   10148     }
   10149 
   10150 #endif
   10151 
   10152     if (mParameters.useJpegExifRotation()) {
   10153         int16_t orientation;
   10154         switch (mParameters.getJpegExifRotation()) {
   10155         case 0:
   10156             orientation = 1;
   10157             break;
   10158         case 90:
   10159             orientation = 6;
   10160             break;
   10161         case 180:
   10162             orientation = 3;
   10163             break;
   10164         case 270:
   10165             orientation = 8;
   10166             break;
   10167         default:
   10168             orientation = 1;
   10169             break;
   10170         }
   10171         exif->addEntry(EXIFTAGID_ORIENTATION,
   10172                 EXIF_SHORT,
   10173                 1,
   10174                 (void *)&orientation);
   10175         exif->addEntry(EXIFTAGID_TN_ORIENTATION,
   10176                 EXIF_SHORT,
   10177                 1,
   10178                 (void *)&orientation);
   10179     }
   10180 
   10181     return exif;
   10182 }
   10183 
   10184 /*===========================================================================
   10185  * FUNCTION   : setHistogram
   10186  *
   10187  * DESCRIPTION: set if histogram should be enabled
   10188  *
   10189  * PARAMETERS :
   10190  *   @histogram_en : bool flag if histogram should be enabled
   10191  *
   10192  * RETURN     : int32_t type of status
   10193  *              NO_ERROR  -- success
   10194  *              none-zero failure code
   10195  *==========================================================================*/
   10196 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
   10197 {
   10198     return mParameters.setHistogram(histogram_en);
   10199 }
   10200 
   10201 /*===========================================================================
   10202  * FUNCTION   : setFaceDetection
   10203  *
   10204  * DESCRIPTION: set if face detection should be enabled
   10205  *
   10206  * PARAMETERS :
   10207  *   @enabled : bool flag if face detection should be enabled
   10208  *
   10209  * RETURN     : int32_t type of status
   10210  *              NO_ERROR  -- success
   10211  *              none-zero failure code
   10212  *==========================================================================*/
   10213 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
   10214 {
   10215     return mParameters.setFaceDetection(enabled, true);
   10216 }
   10217 
   10218 /*===========================================================================
   10219  * FUNCTION   : isCaptureShutterEnabled
   10220  *
   10221  * DESCRIPTION: Check whether shutter should be triggered immediately after
   10222  *              capture
   10223  *
   10224  * PARAMETERS :
   10225  *
   10226  * RETURN     : true - regular capture
   10227  *              false - other type of capture
   10228  *==========================================================================*/
   10229 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
   10230 {
   10231     char prop[PROPERTY_VALUE_MAX];
   10232     memset(prop, 0, sizeof(prop));
   10233     property_get("persist.camera.feature.shutter", prop, "0");
   10234     int enableShutter = atoi(prop);
   10235     return enableShutter == 1;
   10236 }
   10237 
   10238 /*===========================================================================
   10239  * FUNCTION   : needProcessPreviewFrame
   10240  *
   10241  * DESCRIPTION: returns whether preview frame need to be displayed
   10242  *
   10243  * PARAMETERS :
   10244  *   @frameID : frameID of frame to be processed
   10245  *
   10246  * RETURN     : int32_t type of status
   10247  *              NO_ERROR  -- success
   10248  *              none-zero failure code
   10249  *==========================================================================*/
   10250 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
   10251 {
   10252     return (((m_stateMachine.isPreviewRunning()) &&
   10253             (!isDisplayFrameToSkip(frameID)) &&
   10254             (!mParameters.isInstantAECEnabled())) ||
   10255             (isPreviewRestartEnabled()));
   10256 }
   10257 
   10258 /*===========================================================================
   10259  * FUNCTION   : needSendPreviewCallback
   10260  *
   10261  * DESCRIPTION: returns whether preview frame need to callback to APP
   10262  *
   10263  * PARAMETERS :
   10264  *
   10265  * RETURN     : true - need preview frame callbck
   10266  *              false - not send preview frame callback
   10267  *==========================================================================*/
   10268 bool QCamera2HardwareInterface::needSendPreviewCallback()
   10269 {
   10270     return m_stateMachine.isPreviewRunning()
   10271             && (mDataCb != NULL)
   10272             && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
   10273             && m_stateMachine.isPreviewCallbackNeeded();
   10274 };
   10275 
   10276 /*===========================================================================
   10277  * FUNCTION   : setDisplaySkip
   10278  *
   10279  * DESCRIPTION: set range of frames to skip for preview
   10280  *
   10281  * PARAMETERS :
   10282  *   @enabled : TRUE to start skipping frame to display
   10283                 FALSE to stop skipping frame to display
   10284  *   @skipCnt : Number of frame to skip. 0 by default
   10285  *
   10286  * RETURN     : None
   10287  *==========================================================================*/
   10288 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
   10289 {
   10290     pthread_mutex_lock(&mGrallocLock);
   10291     if (enabled) {
   10292         setDisplayFrameSkip();
   10293         setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
   10294     } else {
   10295         setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
   10296     }
   10297     pthread_mutex_unlock(&mGrallocLock);
   10298 }
   10299 
   10300 /*===========================================================================
   10301  * FUNCTION   : setDisplayFrameSkip
   10302  *
   10303  * DESCRIPTION: set range of frames to skip for preview
   10304  *
   10305  * PARAMETERS :
   10306  *   @start   : frameId to start skip
   10307  *   @end     : frameId to stop skip
   10308  *
   10309  * RETURN     : None
   10310  *==========================================================================*/
   10311 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
   10312         uint32_t end)
   10313 {
   10314     if (start == 0) {
   10315         mFrameSkipStart = 0;
   10316         mFrameSkipEnd = 0;
   10317         return;
   10318     }
   10319     if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
   10320         mFrameSkipStart = start;
   10321     }
   10322     if ((end == 0) || (end > mFrameSkipEnd)) {
   10323         mFrameSkipEnd = end;
   10324     }
   10325 }
   10326 
   10327 /*===========================================================================
   10328  * FUNCTION   : isDisplayFrameToSkip
   10329  *
   10330  * DESCRIPTION: function to determin if input frame falls under skip range
   10331  *
   10332  * PARAMETERS :
   10333  *   @frameId : frameId to verify
   10334  *
   10335  * RETURN     : true : need to skip
   10336  *              false: no need to skip
   10337  *==========================================================================*/
   10338 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
   10339 {
   10340     return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
   10341             (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
   10342 }
   10343 
   10344 /*===========================================================================
   10345  * FUNCTION   : getSnapshotHandle
   10346  *
   10347  * DESCRIPTION: Get the camera handle for snapshot based on the bundlesnapshot
   10348  *              flag and active camera state
   10349  *
   10350  * PARAMETERS : None
   10351  *
   10352  * RETURN     : camera handle for snapshot
   10353  *
   10354  *==========================================================================*/
   10355 uint32_t QCamera2HardwareInterface::getSnapshotHandle()
   10356 {
   10357     uint32_t snapshotHandle = 0;
   10358 
   10359     if ((mActiveCameras == MM_CAMERA_DUAL_CAM) && mBundledSnapshot) {
   10360         snapshotHandle = mCameraHandle->camera_handle;
   10361     } else {
   10362         snapshotHandle = (mMasterCamera == MM_CAMERA_TYPE_MAIN) ?
   10363                 get_main_camera_handle(mCameraHandle->camera_handle) :
   10364                 get_aux_camera_handle(mCameraHandle->camera_handle);
   10365     }
   10366 
   10367     return snapshotHandle;
   10368 }
   10369 
   10370 /*===========================================================================
   10371  * FUNCTION   : prepareHardwareForSnapshot
   10372  *
   10373  * DESCRIPTION: prepare hardware for snapshot, such as LED
   10374  *
   10375  * PARAMETERS :
   10376  *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
   10377  *
   10378  * RETURN     : int32_t type of status
   10379  *              NO_ERROR  -- success
   10380  *              none-zero failure code
   10381  *==========================================================================*/
   10382 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
   10383 {
   10384     ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_HW_FOR_SNAPSHOT);
   10385     LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
   10386     return mCameraHandle->ops->prepare_snapshot(getSnapshotHandle(),
   10387                                                 afNeeded);
   10388 }
   10389 
   10390 /*===========================================================================
   10391  * FUNCTION   : needFDMetadata
   10392  *
   10393  * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
   10394  *
   10395  * PARAMETERS :
   10396  *   @channel_type: channel type
   10397  *
   10398   * RETURN     : true: needed
   10399  *              false: no need
   10400  *==========================================================================*/
   10401 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
   10402 {
   10403     //Note: Currently we only process ZSL channel
   10404     bool value = false;
   10405     if(channel_type == QCAMERA_CH_TYPE_ZSL){
   10406         //check if FD requirement is enabled
   10407         if(mParameters.isSnapshotFDNeeded() &&
   10408            mParameters.isFaceDetectionEnabled()){
   10409             value = true;
   10410             LOGH("Face Detection metadata is required in ZSL mode.");
   10411         }
   10412     }
   10413 
   10414     return value;
   10415 }
   10416 
   10417 /*===========================================================================
   10418  * FUNCTION   : deferredWorkRoutine
   10419  *
   10420  * DESCRIPTION: data process routine that executes deferred tasks
   10421  *
   10422  * PARAMETERS :
   10423  *   @data    : user data ptr (QCamera2HardwareInterface)
   10424  *
   10425  * RETURN     : None
   10426  *==========================================================================*/
   10427 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
   10428 {
   10429     int running = 1;
   10430     int ret;
   10431     uint8_t is_active = FALSE;
   10432     int32_t job_status = 0;
   10433 
   10434     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
   10435     QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
   10436     cmdThread->setName("CAM_defrdWrk");
   10437 
   10438     do {
   10439         do {
   10440             ret = cam_sem_wait(&cmdThread->cmd_sem);
   10441             if (ret != 0 && errno != EINVAL) {
   10442                 LOGE("cam_sem_wait error (%s)",
   10443                          strerror(errno));
   10444                 return NULL;
   10445             }
   10446         } while (ret != 0);
   10447 
   10448         // we got notified about new cmd avail in cmd queue
   10449         camera_cmd_type_t cmd = cmdThread->getCmd();
   10450         LOGD("cmd: %d", cmd);
   10451         switch (cmd) {
   10452         case CAMERA_CMD_TYPE_START_DATA_PROC:
   10453             LOGH("start data proc");
   10454             is_active = TRUE;
   10455             break;
   10456         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
   10457             LOGH("stop data proc");
   10458             is_active = FALSE;
   10459             // signal cmd is completed
   10460             cam_sem_post(&cmdThread->sync_sem);
   10461             break;
   10462         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
   10463             {
   10464                 DefWork *dw =
   10465                     reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
   10466 
   10467                 if ( NULL == dw ) {
   10468                     LOGE("Invalid deferred work");
   10469                     break;
   10470                 }
   10471 
   10472                 switch( dw->cmd ) {
   10473                 case CMD_DEF_ALLOCATE_BUFF:
   10474                     {
   10475                         QCameraChannel * pChannel = dw->args.allocArgs.ch;
   10476 
   10477                         if ( NULL == pChannel ) {
   10478                             LOGE("Invalid deferred work channel");
   10479                             job_status = BAD_VALUE;
   10480                             break;
   10481                         }
   10482 
   10483                         cam_stream_type_t streamType = dw->args.allocArgs.type;
   10484                         LOGH("Deferred buffer allocation started for stream type: %d",
   10485                                  streamType);
   10486 
   10487                         uint32_t iNumOfStreams = pChannel->getNumOfStreams();
   10488                         QCameraStream *pStream = NULL;
   10489                         for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
   10490                             pStream = pChannel->getStreamByIndex(i);
   10491 
   10492                             if ( NULL == pStream ) {
   10493                                 job_status = BAD_VALUE;
   10494                                 break;
   10495                             }
   10496 
   10497                             if ( pStream->isTypeOf(streamType)) {
   10498                                 if ( pStream->allocateBuffers() ) {
   10499                                     LOGE("Error allocating buffers !!!");
   10500                                     job_status =  NO_MEMORY;
   10501                                     pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10502                                             CAMERA_ERROR_UNKNOWN, 0);
   10503                                 }
   10504                                 break;
   10505                             }
   10506                         }
   10507                     }
   10508                     break;
   10509                 case CMD_DEF_PPROC_START:
   10510                     {
   10511                         int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
   10512                         if (ret != NO_ERROR) {
   10513                             job_status = ret;
   10514                             LOGE("PPROC Start failed");
   10515                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10516                                     CAMERA_ERROR_UNKNOWN, 0);
   10517                             break;
   10518                         }
   10519                         QCameraChannel * pChannel = dw->args.pprocArgs;
   10520                         assert(pChannel);
   10521 
   10522                         if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
   10523                             LOGE("cannot start postprocessor");
   10524                             job_status = BAD_VALUE;
   10525                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10526                                     CAMERA_ERROR_UNKNOWN, 0);
   10527                         }
   10528                     }
   10529                     break;
   10530                 case CMD_DEF_METADATA_ALLOC:
   10531                     {
   10532                         int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
   10533                         if (ret != NO_ERROR) {
   10534                             job_status = ret;
   10535                             LOGE("Metadata alloc failed");
   10536                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10537                                     CAMERA_ERROR_UNKNOWN, 0);
   10538                             break;
   10539                         }
   10540                         pme->mMetadataMem = new QCameraMetadataStreamMemory(
   10541                                 QCAMERA_ION_USE_CACHE);
   10542 
   10543                         if (pme->mMetadataMem == NULL) {
   10544                             LOGE("Unable to allocate metadata buffers");
   10545                             job_status = BAD_VALUE;
   10546                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10547                                     CAMERA_ERROR_UNKNOWN, 0);
   10548                         } else {
   10549                             int32_t rc = pme->mMetadataMem->allocate(
   10550                                     dw->args.metadataAllocArgs.bufferCnt,
   10551                                     dw->args.metadataAllocArgs.size);
   10552                             if (rc < 0) {
   10553                                 delete pme->mMetadataMem;
   10554                                 pme->mMetadataMem = NULL;
   10555                             }
   10556                         }
   10557                      }
   10558                      break;
   10559                 case CMD_DEF_CREATE_JPEG_SESSION:
   10560                     {
   10561                         QCameraChannel * pChannel = dw->args.pprocArgs;
   10562                         assert(pChannel);
   10563 
   10564                         int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
   10565                         if (ret != NO_ERROR) {
   10566                             job_status = ret;
   10567                             LOGE("Jpeg create failed");
   10568                             break;
   10569                         }
   10570 
   10571                         if (pme->m_postprocessor.createJpegSession(pChannel)
   10572                             != NO_ERROR) {
   10573                             LOGE("cannot create JPEG session");
   10574                             job_status = UNKNOWN_ERROR;
   10575                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10576                                     CAMERA_ERROR_UNKNOWN, 0);
   10577                         }
   10578                     }
   10579                     break;
   10580                 case CMD_DEF_PPROC_INIT:
   10581                     {
   10582                         int32_t rc = NO_ERROR;
   10583 
   10584                         jpeg_encode_callback_t jpegEvtHandle =
   10585                                 dw->args.pprocInitArgs.jpeg_cb;
   10586                         void* user_data = dw->args.pprocInitArgs.user_data;
   10587                         QCameraPostProcessor *postProcessor =
   10588                                 &(pme->m_postprocessor);
   10589                         uint32_t cameraId = pme->mCameraId;
   10590                         cam_capability_t *capability =
   10591                                 gCamCapability[cameraId];
   10592                         cam_padding_info_t padding_info;
   10593                         cam_padding_info_t& cam_capability_padding_info =
   10594                                 capability->padding_info;
   10595 
   10596                         if(!pme->mJpegClientHandle) {
   10597                             rc = pme->initJpegHandle();
   10598                             if (rc != NO_ERROR) {
   10599                                 LOGE("Error!! creating JPEG handle failed");
   10600                                 job_status = UNKNOWN_ERROR;
   10601                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10602                                         CAMERA_ERROR_UNKNOWN, 0);
   10603                                 break;
   10604                             }
   10605                         }
   10606                         LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
   10607 
   10608                         rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
   10609                                 &pme->mJpegMpoHandle,
   10610                                 pme->mJpegClientHandle);
   10611                         if (rc != 0) {
   10612                             LOGE("Error!! set JPEG handle failed");
   10613                             job_status = UNKNOWN_ERROR;
   10614                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10615                                     CAMERA_ERROR_UNKNOWN, 0);
   10616                             break;
   10617                         }
   10618 
   10619                         /* get max pic size for jpeg work buf calculation*/
   10620                         rc = postProcessor->init(jpegEvtHandle, user_data);
   10621 
   10622                         if (rc != NO_ERROR) {
   10623                             LOGE("cannot init postprocessor");
   10624                             job_status = UNKNOWN_ERROR;
   10625                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10626                                     CAMERA_ERROR_UNKNOWN, 0);
   10627                             break;
   10628                         }
   10629 
   10630                         // update padding info from jpeg
   10631                         postProcessor->getJpegPaddingReq(padding_info);
   10632                         if (cam_capability_padding_info.width_padding <
   10633                                 padding_info.width_padding) {
   10634                             cam_capability_padding_info.width_padding =
   10635                                     padding_info.width_padding;
   10636                         }
   10637                         if (cam_capability_padding_info.height_padding <
   10638                                 padding_info.height_padding) {
   10639                             cam_capability_padding_info.height_padding =
   10640                                     padding_info.height_padding;
   10641                         }
   10642                         if (cam_capability_padding_info.plane_padding !=
   10643                                 padding_info.plane_padding) {
   10644                             cam_capability_padding_info.plane_padding =
   10645                                     mm_stream_calc_lcm(
   10646                                     cam_capability_padding_info.plane_padding,
   10647                                     padding_info.plane_padding);
   10648                         }
   10649                         if (cam_capability_padding_info.offset_info.offset_x
   10650                                 != padding_info.offset_info.offset_x) {
   10651                             cam_capability_padding_info.offset_info.offset_x =
   10652                                     mm_stream_calc_lcm (
   10653                                     cam_capability_padding_info.offset_info.offset_x,
   10654                                     padding_info.offset_info.offset_x);
   10655                         }
   10656                         if (cam_capability_padding_info.offset_info.offset_y
   10657                                 != padding_info.offset_info.offset_y) {
   10658                             cam_capability_padding_info.offset_info.offset_y =
   10659                             mm_stream_calc_lcm (
   10660                                     cam_capability_padding_info.offset_info.offset_y,
   10661                                     padding_info.offset_info.offset_y);
   10662                         }
   10663                     }
   10664                     break;
   10665                 case CMD_DEF_PARAM_ALLOC:
   10666                     {
   10667                         int32_t rc = NO_ERROR;
   10668                         if (pme->isDualCamera()) {
   10669                             rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
   10670                         } else {
   10671                             rc = pme->mParameters.allocate();
   10672                         }
   10673                         // notify routine would not be initialized by this time.
   10674                         // So, just update error job status
   10675                         if (rc != NO_ERROR) {
   10676                             job_status = rc;
   10677                             LOGE("Param allocation failed");
   10678                             break;
   10679                         }
   10680                     }
   10681                     break;
   10682                 case CMD_DEF_PARAM_INIT:
   10683                     {
   10684                         int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
   10685                         if (rc != NO_ERROR) {
   10686                             job_status = rc;
   10687                             LOGE("Param init failed");
   10688                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10689                                     CAMERA_ERROR_UNKNOWN, 0);
   10690                             break;
   10691                         }
   10692 
   10693                         uint32_t camId = pme->mCameraId;
   10694                         cam_capability_t * cap = gCamCapability[camId];
   10695 
   10696                         if (pme->mCameraHandle == NULL) {
   10697                             LOGE("Camera handle is null");
   10698                             job_status = BAD_VALUE;
   10699                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10700                                     CAMERA_ERROR_UNKNOWN, 0);
   10701                             break;
   10702                         }
   10703 
   10704                         // Now PostProc need calibration data as initialization
   10705                         // time for jpeg_open and calibration data is a
   10706                         // get param for now, so params needs to be initialized
   10707                         // before postproc init
   10708                         rc = pme->mParameters.init(cap,
   10709                                 pme->mCameraHandle,
   10710                                 pme, pme->m_pFovControl);
   10711                         if (rc != 0) {
   10712                             job_status = UNKNOWN_ERROR;
   10713                             LOGE("Parameter Initialization failed");
   10714                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10715                                     CAMERA_ERROR_UNKNOWN, 0);
   10716                             break;
   10717                         }
   10718 
   10719                         // Get related cam calibration only in
   10720                         // dual camera mode
   10721                         if ((pme->getRelatedCamSyncInfo()->sync_control ==
   10722                                 CAM_SYNC_RELATED_SENSORS_ON) || pme->isDualCamera()){
   10723                             rc = pme->mParameters.getRelatedCamCalibration(
   10724                                 &(pme->mJpegMetadata.otp_calibration_data));
   10725                             LOGD("Dumping Calibration Data Version Id %f rc %d",
   10726                                     pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
   10727                                     rc);
   10728                             if (rc != 0) {
   10729                                 job_status = UNKNOWN_ERROR;
   10730                                 LOGE("getRelatedCamCalibration failed");
   10731                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10732                                         CAMERA_ERROR_UNKNOWN, 0);
   10733                                 break;
   10734                             }
   10735                             pme->m_bRelCamCalibValid = true;
   10736                         }
   10737 
   10738                         pme->mJpegMetadata.sensor_mount_angle =
   10739                             cap->sensor_mount_angle;
   10740                         pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
   10741 
   10742                         pme->mParameters.setMinPpMask(
   10743                             cap->qcom_supported_feature_mask);
   10744                         pme->mExifParams.debug_params =
   10745                                 (mm_jpeg_debug_exif_params_t *)
   10746                                 malloc(sizeof(mm_jpeg_debug_exif_params_t));
   10747                         if (!pme->mExifParams.debug_params) {
   10748                             LOGE("Out of Memory. Allocation failed for "
   10749                                     "3A debug exif params");
   10750                             job_status = NO_MEMORY;
   10751                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10752                                     CAMERA_ERROR_UNKNOWN, 0);
   10753                             break;
   10754                         }
   10755                         memset(pme->mExifParams.debug_params, 0,
   10756                                 sizeof(mm_jpeg_debug_exif_params_t));
   10757                     }
   10758                     break;
   10759                 case CMD_DEF_GENERIC:
   10760                     {
   10761                         BackgroundTask *bgTask = dw->args.genericArgs;
   10762                         job_status = bgTask->bgFunction(bgTask->bgArgs);
   10763                     }
   10764                     break;
   10765                 default:
   10766                     LOGE("Incorrect command : %d", dw->cmd);
   10767                 }
   10768 
   10769                 pme->dequeueDeferredWork(dw, job_status);
   10770             }
   10771             break;
   10772         case CAMERA_CMD_TYPE_EXIT:
   10773             running = 0;
   10774             break;
   10775         default:
   10776             break;
   10777         }
   10778     } while (running);
   10779 
   10780     return NULL;
   10781 }
   10782 
   10783 /*===========================================================================
   10784  * FUNCTION   : queueDeferredWork
   10785  *
   10786  * DESCRIPTION: function which queues deferred tasks
   10787  *
   10788  * PARAMETERS :
   10789  *   @cmd     : deferred task
   10790  *   @args    : deferred task arguments
   10791  *
   10792  * RETURN     : job id of deferred job
   10793  *            : 0 in case of error
   10794  *==========================================================================*/
   10795 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
   10796                                                       DeferWorkArgs args)
   10797 {
   10798     Mutex::Autolock l(mDefLock);
   10799     for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
   10800         if (mDefOngoingJobs[i].mDefJobId == 0) {
   10801             DefWork *dw = new DefWork(cmd, sNextJobId, args);
   10802             if (!dw) {
   10803                 LOGE("out of memory.");
   10804                 return 0;
   10805             }
   10806             if (mCmdQueue.enqueue(dw)) {
   10807                 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
   10808                 mDefOngoingJobs[i].mDefJobStatus = 0;
   10809                 if (sNextJobId == 0) { // handle overflow
   10810                     sNextJobId = 1;
   10811                 }
   10812                 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
   10813                         FALSE,
   10814                         FALSE);
   10815                 return mDefOngoingJobs[i].mDefJobId;
   10816             } else {
   10817                 LOGD("Command queue not active! cmd = %d", cmd);
   10818                 delete dw;
   10819                 return 0;
   10820             }
   10821         }
   10822     }
   10823     return 0;
   10824 }
   10825 
   10826 /*===========================================================================
   10827  * FUNCTION   : initJpegHandle
   10828  *
   10829  * DESCRIPTION: Opens JPEG client and gets a handle.
   10830  *                     Sends Dual cam calibration info if present
   10831  *
   10832  * RETURN     : int32_t type of status
   10833  *              NO_ERROR  -- success
   10834  *              none-zero failure code
   10835  *==========================================================================*/
   10836 int32_t QCamera2HardwareInterface::initJpegHandle() {
   10837     // Check if JPEG client handle is present
   10838     LOGH("E");
   10839     if(!mJpegClientHandle) {
   10840         mm_dimension max_size = {0, 0};
   10841         cam_dimension_t size;
   10842 
   10843         mParameters.getMaxPicSize(size);
   10844         max_size.w = size.width;
   10845         max_size.h = size.height;
   10846 
   10847         if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   10848             if (m_bRelCamCalibValid) {
   10849                 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
   10850                         max_size, &mJpegMetadata);
   10851             } else {
   10852                 mJpegClientHandle =  jpeg_open(&mJpegHandle, &mJpegMpoHandle,
   10853                         max_size, NULL);
   10854             }
   10855         } else {
   10856             mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
   10857         }
   10858         if (!mJpegClientHandle) {
   10859             LOGE("Error !! jpeg_open failed!! ");
   10860             return UNKNOWN_ERROR;
   10861         }
   10862         // Set JPEG initialized as true to signify that this camera
   10863         // has initialized the handle
   10864         mJpegHandleOwner = true;
   10865     }
   10866     LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
   10867              mJpegHandleOwner, mJpegClientHandle, mCameraId);
   10868     return NO_ERROR;
   10869 }
   10870 
   10871 /*===========================================================================
   10872  * FUNCTION   : deinitJpegHandle
   10873  *
   10874  * DESCRIPTION: Closes JPEG client using handle
   10875  *
   10876  * RETURN     : int32_t type of status
   10877  *              NO_ERROR  -- success
   10878  *              none-zero failure code
   10879  *==========================================================================*/
   10880 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
   10881     int32_t rc = NO_ERROR;
   10882     LOGH("E");
   10883     // Check if JPEG client handle is present and inited by this camera
   10884     if(mJpegHandleOwner && mJpegClientHandle) {
   10885         rc = mJpegHandle.close(mJpegClientHandle);
   10886         if (rc != NO_ERROR) {
   10887             LOGE("Error!! Closing mJpegClientHandle: %d failed",
   10888                      mJpegClientHandle);
   10889         }
   10890         memset(&mJpegHandle, 0, sizeof(mJpegHandle));
   10891         memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
   10892         mJpegHandleOwner = false;
   10893     }
   10894     mJpegClientHandle = 0;
   10895     LOGH("X rc = %d", rc);
   10896     return rc;
   10897 }
   10898 
   10899 /*===========================================================================
   10900  * FUNCTION   : setJpegHandleInfo
   10901  *
   10902  * DESCRIPTION: sets JPEG client handle info
   10903  *
   10904  * PARAMETERS:
   10905  *                  @ops                    : JPEG ops
   10906  *                  @mpo_ops             : Jpeg MPO ops
   10907  *                  @pJpegClientHandle : o/p Jpeg Client Handle
   10908  *
   10909  * RETURN     : int32_t type of status
   10910  *              NO_ERROR  -- success
   10911  *              none-zero failure code
   10912  *==========================================================================*/
   10913 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
   10914         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
   10915 
   10916     if (pJpegClientHandle && ops && mpo_ops) {
   10917         LOGH("Setting JPEG client handle %d",
   10918                 pJpegClientHandle);
   10919         memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
   10920         memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
   10921         mJpegClientHandle = pJpegClientHandle;
   10922         return NO_ERROR;
   10923     }
   10924     else {
   10925         LOGE("Error!! No Handle found: %d",
   10926                 pJpegClientHandle);
   10927         return BAD_VALUE;
   10928     }
   10929 }
   10930 
   10931 /*===========================================================================
   10932  * FUNCTION   : getJpegHandleInfo
   10933  *
   10934  * DESCRIPTION: gets JPEG client handle info
   10935  *
   10936  * PARAMETERS:
   10937  *                  @ops                    : JPEG ops
   10938  *                  @mpo_ops             : Jpeg MPO ops
   10939  *                  @pJpegClientHandle : o/p Jpeg Client Handle
   10940  *
   10941  * RETURN     : int32_t type of status
   10942  *              NO_ERROR  -- success
   10943  *              none-zero failure code
   10944  *==========================================================================*/
   10945 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
   10946         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
   10947 
   10948     if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   10949         LOGE("Init PProc Deferred work failed");
   10950         return UNKNOWN_ERROR;
   10951     }
   10952     // Copy JPEG ops if present
   10953     if (ops && mpo_ops && pJpegClientHandle) {
   10954         memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
   10955         memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
   10956         *pJpegClientHandle = mJpegClientHandle;
   10957         LOGH("Getting JPEG client handle %d",
   10958                 pJpegClientHandle);
   10959         return NO_ERROR;
   10960     } else {
   10961         return BAD_VALUE;
   10962     }
   10963 }
   10964 
   10965 /*===========================================================================
   10966  * FUNCTION   : dequeueDeferredWork
   10967  *
   10968  * DESCRIPTION: function which dequeues deferred tasks
   10969  *
   10970  * PARAMETERS :
   10971  *   @dw      : deferred work
   10972  *   @jobStatus: deferred task job status
   10973  *
   10974  * RETURN     : int32_t type of status
   10975  *              NO_ERROR  -- success
   10976  *              none-zero failure code
   10977  *==========================================================================*/
   10978 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
   10979 {
   10980     Mutex::Autolock l(mDefLock);
   10981     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   10982         if (mDefOngoingJobs[i].mDefJobId == dw->id) {
   10983             if (jobStatus != NO_ERROR) {
   10984                 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
   10985                 LOGH("updating job status %d for id %d",
   10986                          jobStatus, dw->id);
   10987             } else {
   10988                 mDefOngoingJobs[i].mDefJobId = 0;
   10989                 mDefOngoingJobs[i].mDefJobStatus = 0;
   10990             }
   10991             delete dw;
   10992             mDefCond.broadcast();
   10993             return NO_ERROR;
   10994         }
   10995     }
   10996 
   10997     return UNKNOWN_ERROR;
   10998 }
   10999 
   11000 /*===========================================================================
   11001  * FUNCTION   : getDefJobStatus
   11002  *
   11003  * DESCRIPTION: Gets if a deferred task is success/fail
   11004  *
   11005  * PARAMETERS :
   11006  *   @job_id  : deferred task id
   11007  *
   11008  * RETURN     : NO_ERROR if the job success, otherwise false
   11009  *
   11010  * PRECONDITION : mDefLock is held by current thread
   11011  *==========================================================================*/
   11012 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
   11013 {
   11014     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   11015         if (mDefOngoingJobs[i].mDefJobId == job_id) {
   11016             if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
   11017                 LOGE("job_id (%d) was failed", job_id);
   11018                 return mDefOngoingJobs[i].mDefJobStatus;
   11019             }
   11020             else
   11021                 return NO_ERROR;
   11022         }
   11023     }
   11024     return NO_ERROR;
   11025 }
   11026 
   11027 
   11028 /*===========================================================================
   11029  * FUNCTION   : checkDeferredWork
   11030  *
   11031  * DESCRIPTION: checks if a deferred task is in progress
   11032  *
   11033  * PARAMETERS :
   11034  *   @job_id  : deferred task id
   11035  *
   11036  * RETURN     : true if the task exists, otherwise false
   11037  *
   11038  * PRECONDITION : mDefLock is held by current thread
   11039  *==========================================================================*/
   11040 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
   11041 {
   11042     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   11043         if (mDefOngoingJobs[i].mDefJobId == job_id) {
   11044             return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
   11045         }
   11046     }
   11047     return false;
   11048 }
   11049 
   11050 /*===========================================================================
   11051  * FUNCTION   : waitDeferredWork
   11052  *
   11053  * DESCRIPTION: waits for a deferred task to finish
   11054  *
   11055  * PARAMETERS :
   11056  *   @job_id  : deferred task id
   11057  *
   11058  * RETURN     : int32_t type of status
   11059  *              NO_ERROR  -- success
   11060  *              none-zero failure code
   11061  *==========================================================================*/
   11062 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
   11063 {
   11064     Mutex::Autolock l(mDefLock);
   11065 
   11066     if (job_id == 0) {
   11067         LOGD("Invalid job id %d", job_id);
   11068         return NO_ERROR;
   11069     }
   11070 
   11071     while (checkDeferredWork(job_id) == true ) {
   11072         mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
   11073     }
   11074     return getDefJobStatus(job_id);
   11075 }
   11076 
   11077 /*===========================================================================
   11078  * FUNCTION   : scheduleBackgroundTask
   11079  *
   11080  * DESCRIPTION: Run a requested task in the deferred thread
   11081  *
   11082  * PARAMETERS :
   11083  *   @bgTask  : Task to perform in the background
   11084  *
   11085  * RETURN     : job id of deferred job
   11086  *            : 0 in case of error
   11087  *==========================================================================*/
   11088 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
   11089 {
   11090     DeferWorkArgs args;
   11091     memset(&args, 0, sizeof(DeferWorkArgs));
   11092     args.genericArgs = bgTask;
   11093 
   11094     return queueDeferredWork(CMD_DEF_GENERIC, args);
   11095 }
   11096 
   11097 /*===========================================================================
   11098  * FUNCTION   : waitForBackgroundTask
   11099  *
   11100  * DESCRIPTION: Wait for a background task to complete
   11101  *
   11102  * PARAMETERS :
   11103  *   @taskId  : Task id to wait for
   11104  *
   11105  * RETURN     : int32_t type of status
   11106  *              NO_ERROR  -- success
   11107  *              none-zero failure code
   11108  *==========================================================================*/
   11109 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
   11110 {
   11111     return waitDeferredWork(taskId);
   11112 }
   11113 
   11114 /*===========================================================================
   11115  * FUNCTION   : needDeferedAllocation
   11116  *
   11117  * DESCRIPTION: Function to decide background task for streams
   11118  *
   11119  * PARAMETERS :
   11120  *   @stream_type  : stream type
   11121  *
   11122  * RETURN     : true - if background task is needed
   11123  *              false -  if background task is NOT needed
   11124  *==========================================================================*/
   11125 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
   11126 {
   11127     if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
   11128             || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
   11129         return FALSE;
   11130     }
   11131 
   11132     if ((stream_type == CAM_STREAM_TYPE_RAW)
   11133             && (mParameters.getofflineRAW() && !mParameters.getQuadraCfa())) {
   11134         return FALSE;
   11135     }
   11136 
   11137     if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
   11138             && (!mParameters.getRecordingHintValue())){
   11139         return TRUE;
   11140     }
   11141 
   11142     if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
   11143             || (stream_type == CAM_STREAM_TYPE_METADATA)
   11144             || (stream_type == CAM_STREAM_TYPE_RAW)
   11145             || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
   11146         return TRUE;
   11147     }
   11148 
   11149     if (stream_type == CAM_STREAM_TYPE_VIDEO) {
   11150         return FALSE;
   11151     }
   11152     return FALSE;
   11153 }
   11154 
   11155 /*===========================================================================
   11156  * FUNCTION   : needSyncCB
   11157  *
   11158  * DESCRIPTION: Decide syncronous callback per stream
   11159  *
   11160  * PARAMETERS :
   11161  *  @stream_type: stream type
   11162  *
   11163  * RETURN     : true - if background task is needed
   11164  *              false -  if background task is NOT needed
   11165  *==========================================================================*/
   11166 bool QCamera2HardwareInterface::needSyncCB(cam_stream_type_t stream_type)
   11167 {
   11168 #ifdef TARGET_TS_MAKEUP
   11169     int whiteLevel, cleanLevel;
   11170     if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == TRUE) {
   11171         return FALSE;
   11172     }
   11173 #endif
   11174 
   11175     char value[PROPERTY_VALUE_MAX];
   11176     property_get("persist.camera.preview.sync_cb", value, "1");
   11177     if ((atoi(value) == 1) && (stream_type == CAM_STREAM_TYPE_PREVIEW)) {
   11178         return TRUE;
   11179     }
   11180     return FALSE;
   11181 }
   11182 
   11183 /*===========================================================================
   11184  * FUNCTION   : isRegularCapture
   11185  *
   11186  * DESCRIPTION: Check configuration for regular catpure
   11187  *
   11188  * PARAMETERS :
   11189  *
   11190  * RETURN     : true - regular capture
   11191  *              false - other type of capture
   11192  *==========================================================================*/
   11193 bool QCamera2HardwareInterface::isRegularCapture()
   11194 {
   11195     bool ret = false;
   11196 
   11197     if (numOfSnapshotsExpected() == 1 &&
   11198         !isLongshotEnabled() &&
   11199         !mParameters.isHDREnabled() &&
   11200         !mParameters.getRecordingHintValue() &&
   11201         !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
   11202             ret = true;
   11203     }
   11204     return ret;
   11205 }
   11206 
   11207 /*===========================================================================
   11208  * FUNCTION   : needOfflineReprocessing
   11209  *
   11210  * DESCRIPTION: Check for offline reprocessing
   11211  *
   11212  * PARAMETERS :
   11213  *
   11214  * RETURN     : true - regular capture
   11215  *              false - other type of capture
   11216  *==========================================================================*/
   11217 bool QCamera2HardwareInterface::needOfflineReprocessing()
   11218 {
   11219     bool ret = false;
   11220     if (isRegularCapture()
   11221             || isDualCamera()) {
   11222         ret = true;
   11223     }
   11224     return ret;
   11225 }
   11226 
   11227 /*===========================================================================
   11228  * FUNCTION   : getLogLevel
   11229  *
   11230  * DESCRIPTION: Reads the log level property into a variable
   11231  *
   11232  * PARAMETERS :
   11233  *   None
   11234  *
   11235  * RETURN     :
   11236  *   None
   11237  *==========================================================================*/
   11238 void QCamera2HardwareInterface::getLogLevel()
   11239 {
   11240     char prop[PROPERTY_VALUE_MAX];
   11241 
   11242     property_get("persist.camera.kpi.debug", prop, "0");
   11243     gKpiDebugLevel = atoi(prop);
   11244     return;
   11245 }
   11246 
   11247 /*===========================================================================
   11248  * FUNCTION   : getSensorType
   11249  *
   11250  * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
   11251  *
   11252  * PARAMETERS :
   11253  *   None
   11254  *
   11255  * RETURN     : Type of sensor - bayer or YUV
   11256  *
   11257  *==========================================================================*/
   11258 cam_sensor_t QCamera2HardwareInterface::getSensorType()
   11259 {
   11260     return gCamCapability[mCameraId]->sensor_type.sens_type;
   11261 }
   11262 
   11263 /*===========================================================================
   11264  * FUNCTION   : startRAWChannel
   11265  *
   11266  * DESCRIPTION: start RAW Channel
   11267  *
   11268  * PARAMETERS :
   11269  *   @pChannel  : Src channel to link this RAW channel.
   11270  *
   11271  * RETURN     : int32_t type of status
   11272  *              NO_ERROR  -- success
   11273  *              none-zero failure code
   11274  *==========================================================================*/
   11275 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
   11276 {
   11277     int32_t rc = NO_ERROR;
   11278     QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
   11279     if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
   11280         // Find and try to link a metadata stream from preview channel
   11281         QCameraStream *pMetaStream = NULL;
   11282 
   11283         if (pMetaChannel != NULL) {
   11284             uint32_t streamNum = pMetaChannel->getNumOfStreams();
   11285             QCameraStream *pStream = NULL;
   11286             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   11287                 pStream = pMetaChannel->getStreamByIndex(i);
   11288                 if ((NULL != pStream) &&
   11289                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
   11290                     pMetaStream = pStream;
   11291                     break;
   11292                 }
   11293             }
   11294 
   11295             if (NULL != pMetaStream) {
   11296                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   11297                 if (NO_ERROR != rc) {
   11298                     LOGE("Metadata stream link failed %d", rc);
   11299                 }
   11300             }
   11301         }
   11302         rc = pChannel->start();
   11303     }
   11304     return rc;
   11305 }
   11306 
   11307 /*===========================================================================
   11308  * FUNCTION   : startRecording
   11309  *
   11310  * DESCRIPTION: start recording impl
   11311  *
   11312  * PARAMETERS : none
   11313  *
   11314  * RETURN     : int32_t type of status
   11315  *              NO_ERROR  -- success
   11316  *              none-zero failure code
   11317  *==========================================================================*/
   11318 int32_t QCamera2HardwareInterface::stopRAWChannel()
   11319 {
   11320     int32_t rc = NO_ERROR;
   11321     rc = stopChannel(QCAMERA_CH_TYPE_RAW);
   11322     return rc;
   11323 }
   11324 
   11325 /*===========================================================================
   11326  * FUNCTION   : isLowPowerMode
   11327  *
   11328  * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
   11329  *
   11330  * PARAMETERS :
   11331  *   None
   11332  *
   11333  * RETURN     : TRUE/FALSE
   11334  *
   11335  *==========================================================================*/
   11336 bool QCamera2HardwareInterface::isLowPowerMode()
   11337 {
   11338     cam_dimension_t dim;
   11339     mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
   11340 
   11341     char prop[PROPERTY_VALUE_MAX];
   11342     property_get("camera.lowpower.record.enable", prop, "0");
   11343     int enable = atoi(prop);
   11344 
   11345     //Enable low power mode if :
   11346     //1. Video resolution is 2k (2048x1080) or above and
   11347     //2. camera.lowpower.record.enable is set
   11348 
   11349     bool isLowpower = mParameters.getRecordingHintValue() && enable
   11350             && ((dim.width * dim.height) >= (2048 * 1080));
   11351     return isLowpower;
   11352 }
   11353 
   11354 /*===========================================================================
   11355  * FUNCTION   : getBootToMonoTimeOffset
   11356  *
   11357  * DESCRIPTION: Calculate offset that is used to convert from
   11358  *              clock domain of boot to monotonic
   11359  *
   11360  * PARAMETERS :
   11361  *   None
   11362  *
   11363  * RETURN     : clock offset between boottime and monotonic time.
   11364  *
   11365  *==========================================================================*/
   11366 nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset()
   11367 {
   11368     // try three times to get the clock offset, choose the one
   11369     // with the minimum gap in measurements.
   11370     const int tries = 3;
   11371     nsecs_t bestGap, measured;
   11372     for (int i = 0; i < tries; ++i) {
   11373         const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
   11374         const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
   11375         const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
   11376         const nsecs_t gap = tmono2 - tmono;
   11377         if (i == 0 || gap < bestGap) {
   11378             bestGap = gap;
   11379             measured = tbase - ((tmono + tmono2) >> 1);
   11380         }
   11381     }
   11382     return measured;
   11383 }
   11384 
   11385 /*===========================================================================
   11386  * FUNCTION   : fillDualCameraFOVControl
   11387  *
   11388  * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
   11389  *
   11390  * PARAMETERS : none
   11391  *
   11392  * RETURN     : none
   11393  *==========================================================================*/
   11394 void QCamera2HardwareInterface::fillDualCameraFOVControl()
   11395 {
   11396     qcamera_sm_internal_evt_payload_t *payload =
   11397        (qcamera_sm_internal_evt_payload_t *)
   11398        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   11399     if (NULL != payload) {
   11400         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   11401         payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
   11402         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   11403         if (rc != NO_ERROR) {
   11404             LOGE("processEvt Dual camera fill FOV control failed");
   11405             free(payload);
   11406             payload = NULL;
   11407         }
   11408     } else {
   11409         LOGE("No memory for Dual camera fill FOV control event");
   11410     }
   11411 }
   11412 
   11413 }; // namespace qcamera
   11414