Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2016, 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 
     66 #define HDR_CONFIDENCE_THRESHOLD 0.4
     67 
     68 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds
     69 
     70 // Very long wait, just to be sure we don't deadlock
     71 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
     72 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
     73 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
     74 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
     75 #define CAMERA_MAX_PARAM_APPLY_DELAY 3
     76 
     77 namespace qcamera {
     78 
     79 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
     80 extern pthread_mutex_t gCamLock;
     81 volatile uint32_t gCamHalLogLevel = 1;
     82 extern uint8_t gNumCameraSessions;
     83 uint32_t QCamera2HardwareInterface::sNextJobId = 1;
     84 
     85 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
     86     .set_preview_window =        QCamera2HardwareInterface::set_preview_window,
     87     .set_callbacks =             QCamera2HardwareInterface::set_CallBacks,
     88     .enable_msg_type =           QCamera2HardwareInterface::enable_msg_type,
     89     .disable_msg_type =          QCamera2HardwareInterface::disable_msg_type,
     90     .msg_type_enabled =          QCamera2HardwareInterface::msg_type_enabled,
     91 
     92     .start_preview =             QCamera2HardwareInterface::start_preview,
     93     .stop_preview =              QCamera2HardwareInterface::stop_preview,
     94     .preview_enabled =           QCamera2HardwareInterface::preview_enabled,
     95     .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,
     96 
     97     .start_recording =           QCamera2HardwareInterface::start_recording,
     98     .stop_recording =            QCamera2HardwareInterface::stop_recording,
     99     .recording_enabled =         QCamera2HardwareInterface::recording_enabled,
    100     .release_recording_frame =   QCamera2HardwareInterface::release_recording_frame,
    101 
    102     .auto_focus =                QCamera2HardwareInterface::auto_focus,
    103     .cancel_auto_focus =         QCamera2HardwareInterface::cancel_auto_focus,
    104 
    105     .take_picture =              QCamera2HardwareInterface::take_picture,
    106     .cancel_picture =            QCamera2HardwareInterface::cancel_picture,
    107 
    108     .set_parameters =            QCamera2HardwareInterface::set_parameters,
    109     .get_parameters =            QCamera2HardwareInterface::get_parameters,
    110     .put_parameters =            QCamera2HardwareInterface::put_parameters,
    111     .send_command =              QCamera2HardwareInterface::send_command,
    112 
    113     .release =                   QCamera2HardwareInterface::release,
    114     .dump =                      QCamera2HardwareInterface::dump,
    115 };
    116 
    117 /*===========================================================================
    118  * FUNCTION   : set_preview_window
    119  *
    120  * DESCRIPTION: set preview window.
    121  *
    122  * PARAMETERS :
    123  *   @device  : ptr to camera device struct
    124  *   @window  : window ops table
    125  *
    126  * RETURN     : int32_t type of status
    127  *              NO_ERROR  -- success
    128  *              none-zero failure code
    129  *==========================================================================*/
    130 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
    131         struct preview_stream_ops *window)
    132 {
    133     ATRACE_CALL();
    134     int rc = NO_ERROR;
    135     QCamera2HardwareInterface *hw =
    136         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    137     if (!hw) {
    138         LOGE("NULL camera device");
    139         return BAD_VALUE;
    140     }
    141     LOGD("E camera id %d window = %p", hw->getCameraId(), window);
    142 
    143     hw->lockAPI();
    144     qcamera_api_result_t apiResult;
    145     rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
    146     if (rc == NO_ERROR) {
    147         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
    148         rc = apiResult.status;
    149     }
    150     hw->unlockAPI();
    151     LOGD("X camera id %d", hw->getCameraId());
    152 
    153     return rc;
    154 }
    155 
    156 /*===========================================================================
    157  * FUNCTION   : set_CallBacks
    158  *
    159  * DESCRIPTION: set callbacks for notify and data
    160  *
    161  * PARAMETERS :
    162  *   @device     : ptr to camera device struct
    163  *   @notify_cb  : notify cb
    164  *   @data_cb    : data cb
    165  *   @data_cb_timestamp  : video data cd with timestamp
    166  *   @get_memory : ops table for request gralloc memory
    167  *   @user       : user data ptr
    168  *
    169  * RETURN     : none
    170  *==========================================================================*/
    171 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
    172         camera_notify_callback notify_cb,
    173         camera_data_callback data_cb,
    174         camera_data_timestamp_callback data_cb_timestamp,
    175         camera_request_memory get_memory,
    176         void *user)
    177 {
    178     ATRACE_CALL();
    179     QCamera2HardwareInterface *hw =
    180         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    181     if (!hw) {
    182         LOGE("NULL camera device");
    183         return;
    184     }
    185     LOGD("E camera id %d", hw->getCameraId());
    186 
    187     qcamera_sm_evt_setcb_payload_t payload;
    188     payload.notify_cb = notify_cb;
    189     payload.data_cb = data_cb;
    190     payload.data_cb_timestamp = data_cb_timestamp;
    191     payload.get_memory = get_memory;
    192     payload.user = user;
    193 
    194     hw->lockAPI();
    195     qcamera_api_result_t apiResult;
    196     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
    197     if (rc == NO_ERROR) {
    198         hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
    199     }
    200     hw->unlockAPI();
    201     LOGD("X camera id %d", hw->getCameraId());
    202 
    203 }
    204 
    205 /*===========================================================================
    206  * FUNCTION   : enable_msg_type
    207  *
    208  * DESCRIPTION: enable certain msg type
    209  *
    210  * PARAMETERS :
    211  *   @device     : ptr to camera device struct
    212  *   @msg_type   : msg type mask
    213  *
    214  * RETURN     : none
    215  *==========================================================================*/
    216 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
    217 {
    218     ATRACE_CALL();
    219     QCamera2HardwareInterface *hw =
    220         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    221     if (!hw) {
    222         LOGE("NULL camera device");
    223         return;
    224     }
    225     LOGD("E camera id %d", hw->getCameraId());
    226 
    227     hw->lockAPI();
    228     qcamera_api_result_t apiResult;
    229     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
    230     if (rc == NO_ERROR) {
    231         hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
    232     }
    233     hw->unlockAPI();
    234     LOGD("X camera id %d", hw->getCameraId());
    235 
    236 }
    237 
    238 /*===========================================================================
    239  * FUNCTION   : disable_msg_type
    240  *
    241  * DESCRIPTION: disable certain msg type
    242  *
    243  * PARAMETERS :
    244  *   @device     : ptr to camera device struct
    245  *   @msg_type   : msg type mask
    246  *
    247  * RETURN     : none
    248  *==========================================================================*/
    249 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
    250 {
    251     ATRACE_CALL();
    252     QCamera2HardwareInterface *hw =
    253         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    254     if (!hw) {
    255         LOGE("NULL camera device");
    256         return;
    257     }
    258     LOGD("E camera id %d", hw->getCameraId());
    259 
    260     hw->lockAPI();
    261     qcamera_api_result_t apiResult;
    262     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
    263     if (rc == NO_ERROR) {
    264         hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
    265     }
    266     hw->unlockAPI();
    267     LOGD("X camera id %d", hw->getCameraId());
    268 
    269 }
    270 
    271 /*===========================================================================
    272  * FUNCTION   : msg_type_enabled
    273  *
    274  * DESCRIPTION: if certain msg type is enabled
    275  *
    276  * PARAMETERS :
    277  *   @device     : ptr to camera device struct
    278  *   @msg_type   : msg type mask
    279  *
    280  * RETURN     : 1 -- enabled
    281  *              0 -- not enabled
    282  *==========================================================================*/
    283 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
    284 {
    285     ATRACE_CALL();
    286     int ret = NO_ERROR;
    287     QCamera2HardwareInterface *hw =
    288         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    289     if (!hw) {
    290         LOGE("NULL camera device");
    291         return BAD_VALUE;
    292     }
    293     LOGD("E camera id %d", hw->getCameraId());
    294 
    295     hw->lockAPI();
    296     qcamera_api_result_t apiResult;
    297     ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
    298     if (ret == NO_ERROR) {
    299         hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
    300         ret = apiResult.enabled;
    301     }
    302     hw->unlockAPI();
    303     LOGD("X camera id %d", hw->getCameraId());
    304 
    305    return ret;
    306 }
    307 
    308 /*===========================================================================
    309  * FUNCTION   : prepare_preview
    310  *
    311  * DESCRIPTION: prepare preview
    312  *
    313  * PARAMETERS :
    314  *   @device  : ptr to camera device struct
    315  *
    316  * RETURN     : int32_t type of status
    317  *              NO_ERROR  -- success
    318  *              none-zero failure code
    319  *==========================================================================*/
    320 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
    321 {
    322     ATRACE_CALL();
    323     int ret = NO_ERROR;
    324     QCamera2HardwareInterface *hw =
    325         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    326     if (!hw) {
    327         LOGE("NULL camera device");
    328         return BAD_VALUE;
    329     }
    330     LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
    331              hw->getCameraId());
    332     hw->lockAPI();
    333     qcamera_api_result_t apiResult;
    334     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
    335     ret = hw->processAPI(evt, NULL);
    336     if (ret == NO_ERROR) {
    337         hw->waitAPIResult(evt, &apiResult);
    338         ret = apiResult.status;
    339     }
    340     hw->unlockAPI();
    341     LOGH("[KPI Perf]: X");
    342     return ret;
    343 }
    344 
    345 
    346 /*===========================================================================
    347  * FUNCTION   : start_preview
    348  *
    349  * DESCRIPTION: start preview
    350  *
    351  * PARAMETERS :
    352  *   @device  : ptr to camera device struct
    353  *
    354  * RETURN     : int32_t type of status
    355  *              NO_ERROR  -- success
    356  *              none-zero failure code
    357  *==========================================================================*/
    358 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
    359 {
    360     KPI_ATRACE_CALL();
    361     int ret = NO_ERROR;
    362     QCamera2HardwareInterface *hw =
    363         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    364     if (!hw) {
    365         LOGE("NULL camera device");
    366         return BAD_VALUE;
    367     }
    368     LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
    369              hw->getCameraId());
    370 
    371     // Release the timed perf lock acquired in openCamera
    372     hw->m_perfLock.lock_rel_timed();
    373 
    374     hw->m_perfLock.lock_acq();
    375     hw->lockAPI();
    376     qcamera_api_result_t apiResult;
    377     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
    378     if (hw->isNoDisplayMode()) {
    379         evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
    380     }
    381     ret = hw->processAPI(evt, NULL);
    382     if (ret == NO_ERROR) {
    383         hw->waitAPIResult(evt, &apiResult);
    384         ret = apiResult.status;
    385     }
    386     hw->unlockAPI();
    387     hw->m_bPreviewStarted = true;
    388     LOGI("[KPI Perf]: X ret = %d", ret);
    389     return ret;
    390 }
    391 
    392 /*===========================================================================
    393  * FUNCTION   : stop_preview
    394  *
    395  * DESCRIPTION: stop preview
    396  *
    397  * PARAMETERS :
    398  *   @device  : ptr to camera device struct
    399  *
    400  * RETURN     : none
    401  *==========================================================================*/
    402 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
    403 {
    404     KPI_ATRACE_CALL();
    405     QCamera2HardwareInterface *hw =
    406         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    407     if (!hw) {
    408         LOGE("NULL camera device");
    409         return;
    410     }
    411     LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
    412              hw->getCameraId());
    413 
    414     // Disable power Hint for preview
    415     hw->m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
    416 
    417     hw->m_perfLock.lock_acq();
    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_CALL();
    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_CALL();
    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_CALL();
    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_CALL();
    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_CALL();
    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     LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
    653           hw->getCameraId());
    654     // Give HWI control to call pre_start_recording in single camera mode.
    655     // In dual-cam mode, this control belongs to muxer.
    656     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    657         ret = pre_start_recording(device);
    658         if (ret != NO_ERROR) {
    659             LOGE("pre_start_recording failed with ret = %d", ret);
    660             return ret;
    661         }
    662     }
    663 
    664     hw->lockAPI();
    665     qcamera_api_result_t apiResult;
    666     ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
    667     if (ret == NO_ERROR) {
    668         hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
    669         ret = apiResult.status;
    670     }
    671     hw->unlockAPI();
    672     hw->m_bRecordStarted = true;
    673     LOGI("[KPI Perf]: X ret = %d", ret);
    674 
    675     return ret;
    676 }
    677 
    678 /*===========================================================================
    679  * FUNCTION   : stop_recording
    680  *
    681  * DESCRIPTION: stop recording
    682  *
    683  * PARAMETERS :
    684  *   @device  : ptr to camera device struct
    685  *
    686  * RETURN     : none
    687  *==========================================================================*/
    688 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
    689 {
    690     ATRACE_CALL();
    691     QCamera2HardwareInterface *hw =
    692         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    693     if (!hw) {
    694         LOGE("NULL camera device");
    695         return;
    696     }
    697     LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
    698              hw->getCameraId());
    699 
    700     hw->lockAPI();
    701     qcamera_api_result_t apiResult;
    702     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
    703     if (ret == NO_ERROR) {
    704         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
    705     }
    706     hw->unlockAPI();
    707     LOGI("[KPI Perf]: X ret = %d", ret);
    708 }
    709 
    710 /*===========================================================================
    711  * FUNCTION   : recording_enabled
    712  *
    713  * DESCRIPTION: if recording is running
    714  *
    715  * PARAMETERS :
    716  *   @device  : ptr to camera device struct
    717  *
    718  * RETURN     : 1 -- running
    719  *              0 -- not running
    720  *==========================================================================*/
    721 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
    722 {
    723     ATRACE_CALL();
    724     int ret = NO_ERROR;
    725     QCamera2HardwareInterface *hw =
    726         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    727     if (!hw) {
    728         LOGE("NULL camera device");
    729         return BAD_VALUE;
    730     }
    731     LOGD("E camera id %d", hw->getCameraId());
    732     hw->lockAPI();
    733     qcamera_api_result_t apiResult;
    734     ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
    735     if (ret == NO_ERROR) {
    736         hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
    737         ret = apiResult.enabled;
    738     }
    739     hw->unlockAPI();
    740     LOGD("X camera id %d", hw->getCameraId());
    741 
    742     return ret;
    743 }
    744 
    745 /*===========================================================================
    746  * FUNCTION   : release_recording_frame
    747  *
    748  * DESCRIPTION: return recording frame back
    749  *
    750  * PARAMETERS :
    751  *   @device  : ptr to camera device struct
    752  *   @opaque  : ptr to frame to be returned
    753  *
    754  * RETURN     : none
    755  *==========================================================================*/
    756 void QCamera2HardwareInterface::release_recording_frame(
    757             struct camera_device *device, const void *opaque)
    758 {
    759     ATRACE_CALL();
    760     QCamera2HardwareInterface *hw =
    761         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    762     if (!hw) {
    763         LOGE("NULL camera device");
    764         return;
    765     }
    766     if (!opaque) {
    767         LOGE("Error!! Frame info is NULL");
    768         return;
    769     }
    770     LOGD("E camera id %d", hw->getCameraId());
    771     hw->lockAPI();
    772     qcamera_api_result_t apiResult;
    773     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
    774     if (ret == NO_ERROR) {
    775         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
    776     }
    777     hw->unlockAPI();
    778     LOGD("X camera id %d", hw->getCameraId());
    779 }
    780 
    781 /*===========================================================================
    782  * FUNCTION   : auto_focus
    783  *
    784  * DESCRIPTION: start auto focus
    785  *
    786  * PARAMETERS :
    787  *   @device  : ptr to camera device struct
    788  *
    789  * RETURN     : int32_t type of status
    790  *              NO_ERROR  -- success
    791  *              none-zero failure code
    792  *==========================================================================*/
    793 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
    794 {
    795     KPI_ATRACE_INT("Camera:AutoFocus", 1);
    796     int ret = NO_ERROR;
    797     QCamera2HardwareInterface *hw =
    798         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    799     if (!hw) {
    800         LOGE("NULL camera device");
    801         return BAD_VALUE;
    802     }
    803     LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
    804              hw->getCameraId());
    805     hw->lockAPI();
    806     qcamera_api_result_t apiResult;
    807     ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
    808     if (ret == NO_ERROR) {
    809         hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
    810         ret = apiResult.status;
    811     }
    812     hw->unlockAPI();
    813     LOGH("[KPI Perf] : X ret = %d", ret);
    814 
    815     return ret;
    816 }
    817 
    818 /*===========================================================================
    819  * FUNCTION   : cancel_auto_focus
    820  *
    821  * DESCRIPTION: cancel auto focus
    822  *
    823  * PARAMETERS :
    824  *   @device  : ptr to camera device struct
    825  *
    826  * RETURN     : int32_t type of status
    827  *              NO_ERROR  -- success
    828  *              none-zero failure code
    829  *==========================================================================*/
    830 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
    831 {
    832     ATRACE_CALL();
    833     int ret = NO_ERROR;
    834     QCamera2HardwareInterface *hw =
    835         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    836     if (!hw) {
    837         LOGE("NULL camera device");
    838         return BAD_VALUE;
    839     }
    840     LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
    841              hw->getCameraId());
    842     hw->lockAPI();
    843     qcamera_api_result_t apiResult;
    844     ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
    845     if (ret == NO_ERROR) {
    846         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
    847         ret = apiResult.status;
    848     }
    849     hw->unlockAPI();
    850     LOGH("[KPI Perf] : X ret = %d", ret);
    851     return ret;
    852 }
    853 
    854 /*===========================================================================
    855  * FUNCTION   : pre_take_picture
    856  *
    857  * DESCRIPTION: pre take picture, restart preview if necessary.
    858  *
    859  * PARAMETERS :
    860  *   @device  : ptr to camera device struct
    861  *
    862  * RETURN     : int32_t type of status
    863  *              NO_ERROR  -- success
    864  *              none-zero failure code
    865  *==========================================================================*/
    866 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
    867 {
    868     ATRACE_CALL();
    869     int ret = NO_ERROR;
    870     QCamera2HardwareInterface *hw =
    871         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    872     if (!hw) {
    873         LOGE("NULL camera device");
    874         return BAD_VALUE;
    875     }
    876     LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
    877           hw->getCameraId());
    878     hw->lockAPI();
    879     qcamera_api_result_t apiResult;
    880     ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
    881     if (ret == NO_ERROR) {
    882         hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
    883         ret = apiResult.status;
    884     }
    885     hw->unlockAPI();
    886     LOGH("[KPI Perf]: X");
    887     return ret;
    888 }
    889 
    890 /*===========================================================================
    891  * FUNCTION   : take_picture
    892  *
    893  * DESCRIPTION: take picture
    894  *
    895  * PARAMETERS :
    896  *   @device  : ptr to camera device struct
    897  *
    898  * RETURN     : int32_t type of status
    899  *              NO_ERROR  -- success
    900  *              none-zero failure code
    901  *==========================================================================*/
    902 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
    903 {
    904     KPI_ATRACE_CALL();
    905     int ret = NO_ERROR;
    906     QCamera2HardwareInterface *hw =
    907         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    908     if (!hw) {
    909         LOGE("NULL camera device");
    910         return BAD_VALUE;
    911     }
    912     LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
    913              hw->getCameraId());
    914     if (!hw->mLongshotEnabled) {
    915         hw->m_perfLock.lock_acq();
    916     }
    917     qcamera_api_result_t apiResult;
    918 
    919    /** Added support for Retro-active Frames:
    920      *  takePicture() is called before preparing Snapshot to indicate the
    921      *  mm-camera-channel to pick up legacy frames even
    922      *  before LED estimation is triggered.
    923      */
    924 
    925     LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
    926            hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
    927            hw->isLongshotEnabled());
    928 
    929     // Check for Retro-active Frames
    930     if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
    931         !hw->isLiveSnapshot() && hw->isZSLMode() &&
    932         !hw->isHDRMode() && !hw->isLongshotEnabled()) {
    933         // Set Retro Picture Mode
    934         hw->setRetroPicture(1);
    935         hw->m_bLedAfAecLock = 0;
    936         LOGL("Retro Enabled");
    937 
    938         // Give HWI control to call pre_take_picture in single camera mode.
    939         // In dual-cam mode, this control belongs to muxer.
    940         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    941             ret = pre_take_picture(device);
    942             if (ret != NO_ERROR) {
    943                 LOGE("pre_take_picture failed with ret = %d",ret);
    944                 return ret;
    945             }
    946         }
    947 
    948         /* Call take Picture for total number of snapshots required.
    949              This includes the number of retro frames and normal frames */
    950         hw->lockAPI();
    951         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
    952         if (ret == NO_ERROR) {
    953           // Wait for retro frames, before calling prepare snapshot
    954           LOGD("Wait for Retro frames to be done");
    955           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
    956             ret = apiResult.status;
    957         }
    958         /* Unlock API since it is acquired in prepare snapshot seperately */
    959         hw->unlockAPI();
    960 
    961         /* Prepare snapshot in case LED needs to be flashed */
    962         LOGD("Start Prepare Snapshot");
    963         ret = hw->prepare_snapshot(device);
    964     }
    965     else {
    966         hw->setRetroPicture(0);
    967         // Check if prepare snapshot is done
    968         if (!hw->mPrepSnapRun) {
    969             // Ignore the status from prepare_snapshot
    970             hw->prepare_snapshot(device);
    971         }
    972 
    973         // Give HWI control to call pre_take_picture in single camera mode.
    974         // In dual-cam mode, this control belongs to muxer.
    975         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    976             ret = pre_take_picture(device);
    977             if (ret != NO_ERROR) {
    978                 LOGE("pre_take_picture failed with ret = %d",ret);
    979                 return ret;
    980             }
    981         }
    982 
    983         // Regardless what the result value for prepare_snapshot,
    984         // go ahead with capture anyway. Just like the way autofocus
    985         // is handled in capture case
    986         /* capture */
    987         LOGL("Capturing normal frames");
    988         hw->lockAPI();
    989         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
    990         if (ret == NO_ERROR) {
    991           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
    992             ret = apiResult.status;
    993         }
    994         hw->unlockAPI();
    995         if (!hw->isLongshotEnabled()){
    996             // For longshot mode, we prepare snapshot only once
    997             hw->mPrepSnapRun = false;
    998          }
    999     }
   1000     LOGI("[KPI Perf]: X ret = %d", ret);
   1001     return ret;
   1002 }
   1003 
   1004 /*===========================================================================
   1005  * FUNCTION   : cancel_picture
   1006  *
   1007  * DESCRIPTION: cancel current take picture request
   1008  *
   1009  * PARAMETERS :
   1010  *   @device  : ptr to camera device struct
   1011  *
   1012  * RETURN     : int32_t type of status
   1013  *              NO_ERROR  -- success
   1014  *              none-zero failure code
   1015  *==========================================================================*/
   1016 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
   1017 {
   1018     ATRACE_CALL();
   1019     int ret = NO_ERROR;
   1020     QCamera2HardwareInterface *hw =
   1021         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1022     if (!hw) {
   1023         LOGE("NULL camera device");
   1024         return BAD_VALUE;
   1025     }
   1026     LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
   1027              hw->getCameraId());
   1028     hw->lockAPI();
   1029     qcamera_api_result_t apiResult;
   1030     ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
   1031     if (ret == NO_ERROR) {
   1032         hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
   1033         ret = apiResult.status;
   1034     }
   1035     hw->unlockAPI();
   1036     LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);
   1037 
   1038     return ret;
   1039 }
   1040 
   1041 /*===========================================================================
   1042  * FUNCTION   : set_parameters
   1043  *
   1044  * DESCRIPTION: set camera parameters
   1045  *
   1046  * PARAMETERS :
   1047  *   @device  : ptr to camera device struct
   1048  *   @parms   : string of packed parameters
   1049  *
   1050  * RETURN     : int32_t type of status
   1051  *              NO_ERROR  -- success
   1052  *              none-zero failure code
   1053  *==========================================================================*/
   1054 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
   1055                                               const char *parms)
   1056 {
   1057     ATRACE_CALL();
   1058     int ret = NO_ERROR;
   1059     QCamera2HardwareInterface *hw =
   1060         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1061     if (!hw) {
   1062         LOGE("NULL camera device");
   1063         return BAD_VALUE;
   1064     }
   1065     LOGD("E camera id %d", hw->getCameraId());
   1066     hw->lockAPI();
   1067     qcamera_api_result_t apiResult;
   1068     ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
   1069     if (ret == NO_ERROR) {
   1070         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
   1071         ret = apiResult.status;
   1072     }
   1073 
   1074     // Give HWI control to restart (if necessary) after set params
   1075     // in single camera mode. In dual-cam mode, this control belongs to muxer.
   1076     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   1077         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
   1078             LOGD("stopping after param change");
   1079             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
   1080             if (ret == NO_ERROR) {
   1081                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
   1082                 ret = apiResult.status;
   1083             }
   1084         }
   1085 
   1086         if (ret == NO_ERROR) {
   1087             LOGD("committing param change");
   1088             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
   1089             if (ret == NO_ERROR) {
   1090                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
   1091                 ret = apiResult.status;
   1092             }
   1093         }
   1094 
   1095         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
   1096             LOGD("restarting after param change");
   1097             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
   1098             if (ret == NO_ERROR) {
   1099                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
   1100                 ret = apiResult.status;
   1101             }
   1102         }
   1103     }
   1104 
   1105     hw->unlockAPI();
   1106     LOGD("X camera id %d ret %d", hw->getCameraId(), ret);
   1107 
   1108     return ret;
   1109 }
   1110 
   1111 /*===========================================================================
   1112  * FUNCTION   : stop_after_set_params
   1113  *
   1114  * DESCRIPTION: stop after a set param call, if necessary
   1115  *
   1116  * PARAMETERS :
   1117  *   @device  : ptr to camera device struct
   1118  *
   1119  * RETURN     : int32_t type of status
   1120  *              NO_ERROR  -- success
   1121  *              none-zero failure code
   1122  *==========================================================================*/
   1123 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
   1124 {
   1125     ATRACE_CALL();
   1126     int ret = NO_ERROR;
   1127     QCamera2HardwareInterface *hw =
   1128         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1129     if (!hw) {
   1130         LOGE("NULL camera device");
   1131         return BAD_VALUE;
   1132     }
   1133     LOGD("E camera id %d", hw->getCameraId());
   1134     hw->lockAPI();
   1135     qcamera_api_result_t apiResult;
   1136 
   1137     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1138         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
   1139         if (ret == NO_ERROR) {
   1140             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
   1141             ret = apiResult.status;
   1142         }
   1143     } else {
   1144         LOGE("is not supposed to be called in single-camera mode");
   1145         ret = INVALID_OPERATION;
   1146     }
   1147 
   1148     hw->unlockAPI();
   1149     LOGD("X camera id %d", hw->getCameraId());
   1150 
   1151     return ret;
   1152 }
   1153 
   1154 /*===========================================================================
   1155  * FUNCTION   : commit_params
   1156  *
   1157  * DESCRIPTION: commit after a set param call
   1158  *
   1159  * PARAMETERS :
   1160  *   @device  : ptr to camera device struct
   1161  *
   1162  * RETURN     : int32_t type of status
   1163  *              NO_ERROR  -- success
   1164  *              none-zero failure code
   1165  *==========================================================================*/
   1166 int QCamera2HardwareInterface::commit_params(struct camera_device *device)
   1167 {
   1168     ATRACE_CALL();
   1169     int ret = NO_ERROR;
   1170     QCamera2HardwareInterface *hw =
   1171         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1172     if (!hw) {
   1173         LOGE("NULL camera device");
   1174         return BAD_VALUE;
   1175     }
   1176     LOGD("E camera id %d", hw->getCameraId());
   1177     hw->lockAPI();
   1178     qcamera_api_result_t apiResult;
   1179 
   1180     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1181         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
   1182         if (ret == NO_ERROR) {
   1183             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
   1184             ret = apiResult.status;
   1185         }
   1186     } else {
   1187         LOGE("is not supposed to be called in single-camera mode");
   1188         ret = INVALID_OPERATION;
   1189     }
   1190 
   1191     hw->unlockAPI();
   1192     LOGD("X camera id %d", hw->getCameraId());
   1193 
   1194     return ret;
   1195 }
   1196 
   1197 /*===========================================================================
   1198  * FUNCTION   : restart_after_set_params
   1199  *
   1200  * DESCRIPTION: restart after a set param call, if necessary
   1201  *
   1202  * PARAMETERS :
   1203  *   @device  : ptr to camera device struct
   1204  *
   1205  * RETURN     : int32_t type of status
   1206  *              NO_ERROR  -- success
   1207  *              none-zero failure code
   1208  *==========================================================================*/
   1209 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
   1210 {
   1211     ATRACE_CALL();
   1212     int ret = NO_ERROR;
   1213     QCamera2HardwareInterface *hw =
   1214         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1215     if (!hw) {
   1216         LOGE("NULL camera device");
   1217         return BAD_VALUE;
   1218     }
   1219     LOGD("E camera id %d", hw->getCameraId());
   1220     hw->lockAPI();
   1221     qcamera_api_result_t apiResult;
   1222 
   1223     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1224         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
   1225         if (ret == NO_ERROR) {
   1226             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
   1227             ret = apiResult.status;
   1228         }
   1229     } else {
   1230         LOGE("is not supposed to be called in single-camera mode");
   1231         ret = INVALID_OPERATION;
   1232     }
   1233 
   1234     hw->unlockAPI();
   1235     LOGD("X camera id %d", hw->getCameraId());
   1236     return ret;
   1237 }
   1238 
   1239 /*===========================================================================
   1240  * FUNCTION   : get_parameters
   1241  *
   1242  * DESCRIPTION: query camera parameters
   1243  *
   1244  * PARAMETERS :
   1245  *   @device  : ptr to camera device struct
   1246  *
   1247  * RETURN     : packed parameters in a string
   1248  *==========================================================================*/
   1249 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
   1250 {
   1251     ATRACE_CALL();
   1252     char *ret = NULL;
   1253     QCamera2HardwareInterface *hw =
   1254         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1255     if (!hw) {
   1256         LOGE("NULL camera device");
   1257         return NULL;
   1258     }
   1259     LOGD("E camera id %d", hw->getCameraId());
   1260     hw->lockAPI();
   1261     qcamera_api_result_t apiResult;
   1262     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
   1263     if (rc == NO_ERROR) {
   1264         hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
   1265         ret = apiResult.params;
   1266     }
   1267     hw->unlockAPI();
   1268     LOGD("E camera id %d", hw->getCameraId());
   1269 
   1270     return ret;
   1271 }
   1272 
   1273 /*===========================================================================
   1274  * FUNCTION   : put_parameters
   1275  *
   1276  * DESCRIPTION: return camera parameters string back to HAL
   1277  *
   1278  * PARAMETERS :
   1279  *   @device  : ptr to camera device struct
   1280  *   @parm    : ptr to parameter string to be returned
   1281  *
   1282  * RETURN     : none
   1283  *==========================================================================*/
   1284 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
   1285                                                char *parm)
   1286 {
   1287     ATRACE_CALL();
   1288     QCamera2HardwareInterface *hw =
   1289         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1290     if (!hw) {
   1291         LOGE("NULL camera device");
   1292         return;
   1293     }
   1294     LOGD("E camera id %d", hw->getCameraId());
   1295     hw->lockAPI();
   1296     qcamera_api_result_t apiResult;
   1297     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
   1298     if (ret == NO_ERROR) {
   1299         hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
   1300     }
   1301     hw->unlockAPI();
   1302     LOGD("E camera id %d", hw->getCameraId());
   1303 }
   1304 
   1305 /*===========================================================================
   1306  * FUNCTION   : send_command
   1307  *
   1308  * DESCRIPTION: command to be executed
   1309  *
   1310  * PARAMETERS :
   1311  *   @device  : ptr to camera device struct
   1312  *   @cmd     : cmd to be executed
   1313  *   @arg1    : ptr to optional argument1
   1314  *   @arg2    : ptr to optional argument2
   1315  *
   1316  * RETURN     : int32_t type of status
   1317  *              NO_ERROR  -- success
   1318  *              none-zero failure code
   1319  *==========================================================================*/
   1320 int QCamera2HardwareInterface::send_command(struct camera_device *device,
   1321                                             int32_t cmd,
   1322                                             int32_t arg1,
   1323                                             int32_t arg2)
   1324 {
   1325     ATRACE_CALL();
   1326     int ret = NO_ERROR;
   1327     QCamera2HardwareInterface *hw =
   1328         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1329     if (!hw) {
   1330         LOGE("NULL camera device");
   1331         return BAD_VALUE;
   1332     }
   1333     LOGD("E camera id %d", hw->getCameraId());
   1334 
   1335     qcamera_sm_evt_command_payload_t payload;
   1336     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
   1337     payload.cmd = cmd;
   1338     payload.arg1 = arg1;
   1339     payload.arg2 = arg2;
   1340     hw->lockAPI();
   1341     qcamera_api_result_t apiResult;
   1342     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
   1343     if (ret == NO_ERROR) {
   1344         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
   1345         ret = apiResult.status;
   1346     }
   1347     hw->unlockAPI();
   1348     LOGD("E camera id %d", hw->getCameraId());
   1349 
   1350     return ret;
   1351 }
   1352 
   1353 /*===========================================================================
   1354  * FUNCTION   : send_command_restart
   1355  *
   1356  * DESCRIPTION: restart if necessary after a send_command
   1357  *
   1358  * PARAMETERS :
   1359  *   @device  : ptr to camera device struct
   1360  *   @cmd     : cmd to be executed
   1361  *   @arg1    : ptr to optional argument1
   1362  *   @arg2    : ptr to optional argument2
   1363  *
   1364  * RETURN     : int32_t type of status
   1365  *              NO_ERROR  -- success
   1366  *              none-zero failure code
   1367  *==========================================================================*/
   1368 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
   1369         int32_t cmd,
   1370         int32_t arg1,
   1371         int32_t arg2)
   1372 {
   1373     ATRACE_CALL();
   1374     int ret = NO_ERROR;
   1375     QCamera2HardwareInterface *hw =
   1376             reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1377     if (!hw) {
   1378         LOGE("NULL camera device");
   1379         return BAD_VALUE;
   1380     }
   1381 
   1382     qcamera_sm_evt_command_payload_t payload;
   1383     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
   1384     payload.cmd = cmd;
   1385     payload.arg1 = arg1;
   1386     payload.arg2 = arg2;
   1387     hw->lockAPI();
   1388     qcamera_api_result_t apiResult;
   1389     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
   1390     if (ret == NO_ERROR) {
   1391         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
   1392         ret = apiResult.status;
   1393     }
   1394     hw->unlockAPI();
   1395     LOGD("E camera id %d", hw->getCameraId());
   1396 
   1397     return ret;
   1398 }
   1399 
   1400 /*===========================================================================
   1401  * FUNCTION   : release
   1402  *
   1403  * DESCRIPTION: release camera resource
   1404  *
   1405  * PARAMETERS :
   1406  *   @device  : ptr to camera device struct
   1407  *
   1408  * RETURN     : none
   1409  *==========================================================================*/
   1410 void QCamera2HardwareInterface::release(struct camera_device *device)
   1411 {
   1412     ATRACE_CALL();
   1413     QCamera2HardwareInterface *hw =
   1414         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1415     if (!hw) {
   1416         LOGE("NULL camera device");
   1417         return;
   1418     }
   1419     LOGD("E camera id %d", hw->getCameraId());
   1420     hw->lockAPI();
   1421     qcamera_api_result_t apiResult;
   1422     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
   1423     if (ret == NO_ERROR) {
   1424         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
   1425     }
   1426     hw->unlockAPI();
   1427     LOGD("E camera id %d", hw->getCameraId());
   1428 }
   1429 
   1430 /*===========================================================================
   1431  * FUNCTION   : dump
   1432  *
   1433  * DESCRIPTION: dump camera status
   1434  *
   1435  * PARAMETERS :
   1436  *   @device  : ptr to camera device struct
   1437  *   @fd      : fd for status to be dumped to
   1438  *
   1439  * RETURN     : int32_t type of status
   1440  *              NO_ERROR  -- success
   1441  *              none-zero failure code
   1442  *==========================================================================*/
   1443 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
   1444 {
   1445     int ret = NO_ERROR;
   1446 
   1447     //Log level property is read when "adb shell dumpsys media.camera" is
   1448     //called so that the log level can be controlled without restarting
   1449     //media server
   1450     getLogLevel();
   1451     QCamera2HardwareInterface *hw =
   1452         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1453     if (!hw) {
   1454         LOGE("NULL camera device");
   1455         return BAD_VALUE;
   1456     }
   1457     LOGD("E camera id %d", hw->getCameraId());
   1458     hw->lockAPI();
   1459     qcamera_api_result_t apiResult;
   1460     ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
   1461     if (ret == NO_ERROR) {
   1462         hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
   1463         ret = apiResult.status;
   1464     }
   1465     hw->unlockAPI();
   1466     LOGD("E camera id %d", hw->getCameraId());
   1467 
   1468     return ret;
   1469 }
   1470 
   1471 /*===========================================================================
   1472  * FUNCTION   : close_camera_device
   1473  *
   1474  * DESCRIPTION: close camera device
   1475  *
   1476  * PARAMETERS :
   1477  *   @device  : ptr to camera device struct
   1478  *
   1479  * RETURN     : int32_t type of status
   1480  *              NO_ERROR  -- success
   1481  *              none-zero failure code
   1482  *==========================================================================*/
   1483 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
   1484 {
   1485     KPI_ATRACE_CALL();
   1486     int ret = NO_ERROR;
   1487 
   1488     QCamera2HardwareInterface *hw =
   1489         reinterpret_cast<QCamera2HardwareInterface *>(
   1490             reinterpret_cast<camera_device_t *>(hw_dev)->priv);
   1491     if (!hw) {
   1492         LOGE("NULL camera device");
   1493         return BAD_VALUE;
   1494     }
   1495     LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
   1496     delete hw;
   1497     LOGI("[KPI Perf]: X");
   1498     return ret;
   1499 }
   1500 
   1501 /*===========================================================================
   1502  * FUNCTION   : register_face_image
   1503  *
   1504  * DESCRIPTION: register a face image into imaging lib for face authenticatio/
   1505  *              face recognition
   1506  *
   1507  * PARAMETERS :
   1508  *   @device  : ptr to camera device struct
   1509  *   @img_ptr : ptr to image buffer
   1510  *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
   1511  *
   1512  * RETURN     : >=0 unique ID of face registerd.
   1513  *              <0  failure.
   1514  *==========================================================================*/
   1515 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
   1516                                                    void *img_ptr,
   1517                                                    cam_pp_offline_src_config_t *config)
   1518 {
   1519     ATRACE_CALL();
   1520     int ret = NO_ERROR;
   1521     QCamera2HardwareInterface *hw =
   1522         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1523     if (!hw) {
   1524         LOGE("NULL camera device");
   1525         return BAD_VALUE;
   1526     }
   1527     LOGD("E camera id %d", hw->getCameraId());
   1528     qcamera_sm_evt_reg_face_payload_t payload;
   1529     memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
   1530     payload.img_ptr = img_ptr;
   1531     payload.config = config;
   1532     hw->lockAPI();
   1533     qcamera_api_result_t apiResult;
   1534     ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
   1535     if (ret == NO_ERROR) {
   1536         hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
   1537         ret = apiResult.handle;
   1538     }
   1539     hw->unlockAPI();
   1540     LOGD("E camera id %d", hw->getCameraId());
   1541 
   1542     return ret;
   1543 }
   1544 
   1545 /*===========================================================================
   1546  * FUNCTION   : prepare_snapshot
   1547  *
   1548  * DESCRIPTION: prepares hardware for snapshot
   1549  *
   1550  * PARAMETERS :
   1551  *   @device  : ptr to camera device struct
   1552  *
   1553  * RETURN     : int32_t type of status
   1554  *              NO_ERROR  -- success
   1555  *              none-zero failure code
   1556  *==========================================================================*/
   1557 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
   1558 {
   1559     ATRACE_CALL();
   1560     int ret = NO_ERROR;
   1561     QCamera2HardwareInterface *hw =
   1562         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1563     if (!hw) {
   1564         LOGE("NULL camera device");
   1565         return BAD_VALUE;
   1566     }
   1567     if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
   1568         // For longshot mode, we prepare snapshot only once
   1569         LOGH("prepare snapshot only once ");
   1570         return NO_ERROR;
   1571     }
   1572     LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
   1573              hw->getCameraId());
   1574     hw->lockAPI();
   1575     qcamera_api_result_t apiResult;
   1576 
   1577     /* Prepare snapshot in case LED needs to be flashed */
   1578     if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
   1579         /* Prepare snapshot in case LED needs to be flashed */
   1580         ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
   1581         if (ret == NO_ERROR) {
   1582           hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
   1583             ret = apiResult.status;
   1584         }
   1585         hw->mPrepSnapRun = true;
   1586     }
   1587     hw->unlockAPI();
   1588     LOGH("[KPI Perf]: X, ret: %d", ret);
   1589     return ret;
   1590 }
   1591 
   1592 /*===========================================================================
   1593  * FUNCTION   : QCamera2HardwareInterface
   1594  *
   1595  * DESCRIPTION: constructor of QCamera2HardwareInterface
   1596  *
   1597  * PARAMETERS :
   1598  *   @cameraId  : camera ID
   1599  *
   1600  * RETURN     : none
   1601  *==========================================================================*/
   1602 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
   1603     : mCameraId(cameraId),
   1604       mCameraHandle(NULL),
   1605       mCameraOpened(false),
   1606       m_bRelCamCalibValid(false),
   1607       mPreviewWindow(NULL),
   1608       mMsgEnabled(0),
   1609       mStoreMetaDataInFrame(0),
   1610       mJpegCb(NULL),
   1611       mCallbackCookie(NULL),
   1612       mJpegCallbackCookie(NULL),
   1613       m_bMpoEnabled(TRUE),
   1614       m_stateMachine(this),
   1615       m_smThreadActive(true),
   1616       m_postprocessor(this),
   1617       m_thermalAdapter(QCameraThermalAdapter::getInstance()),
   1618       m_cbNotifier(this),
   1619       m_bPreviewStarted(false),
   1620       m_bRecordStarted(false),
   1621       m_currentFocusState(CAM_AF_STATE_INACTIVE),
   1622       mDumpFrmCnt(0U),
   1623       mDumpSkipCnt(0U),
   1624       mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
   1625       mActiveAF(false),
   1626       m_HDRSceneEnabled(false),
   1627       mLongshotEnabled(false),
   1628       mLiveSnapshotThread(0),
   1629       mIntPicThread(0),
   1630       mFlashNeeded(false),
   1631       mDeviceRotation(0U),
   1632       mCaptureRotation(0U),
   1633       mJpegExifRotation(0U),
   1634       mUseJpegExifRotation(false),
   1635       mIs3ALocked(false),
   1636       mPrepSnapRun(false),
   1637       mZoomLevel(0),
   1638       mPreviewRestartNeeded(false),
   1639       mVFrameCount(0),
   1640       mVLastFrameCount(0),
   1641       mVLastFpsTime(0),
   1642       mVFps(0),
   1643       mPFrameCount(0),
   1644       mPLastFrameCount(0),
   1645       mPLastFpsTime(0),
   1646       mPFps(0),
   1647       mInstantAecFrameCount(0),
   1648       m_bIntJpegEvtPending(false),
   1649       m_bIntRawEvtPending(false),
   1650       mReprocJob(0),
   1651       mJpegJob(0),
   1652       mMetadataAllocJob(0),
   1653       mInitPProcJob(0),
   1654       mParamAllocJob(0),
   1655       mParamInitJob(0),
   1656       mOutputCount(0),
   1657       mInputCount(0),
   1658       mAdvancedCaptureConfigured(false),
   1659       mHDRBracketingEnabled(false),
   1660       mNumPreviewFaces(-1),
   1661       mJpegClientHandle(0),
   1662       mJpegHandleOwner(false),
   1663       mMetadataMem(NULL),
   1664       mCACDoneReceived(false),
   1665       m_bNeedRestart(false)
   1666 {
   1667 #ifdef TARGET_TS_MAKEUP
   1668     memset(&mFaceRect, -1, sizeof(mFaceRect));
   1669 #endif
   1670     getLogLevel();
   1671     ATRACE_CALL();
   1672     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
   1673     mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
   1674     mCameraDevice.common.close = close_camera_device;
   1675     mCameraDevice.ops = &mCameraOps;
   1676     mCameraDevice.priv = this;
   1677 
   1678     pthread_mutex_init(&m_lock, NULL);
   1679     pthread_cond_init(&m_cond, NULL);
   1680 
   1681     m_apiResultList = NULL;
   1682 
   1683     pthread_mutex_init(&m_evtLock, NULL);
   1684     pthread_cond_init(&m_evtCond, NULL);
   1685     memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
   1686 
   1687 
   1688     pthread_mutex_init(&m_int_lock, NULL);
   1689     pthread_cond_init(&m_int_cond, NULL);
   1690 
   1691     memset(m_channels, 0, sizeof(m_channels));
   1692 
   1693     memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
   1694 
   1695     memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
   1696 
   1697     memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
   1698     memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
   1699     memset(&mJpegHandle, 0, sizeof(mJpegHandle));
   1700     memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
   1701 
   1702     mDeferredWorkThread.launch(deferredWorkRoutine, this);
   1703     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
   1704     m_perfLock.lock_init();
   1705 
   1706     pthread_mutex_init(&mGrallocLock, NULL);
   1707     mEnqueuedBuffers = 0;
   1708     mFrameSkipStart = 0;
   1709     mFrameSkipEnd = 0;
   1710     mLastPreviewFrameID = 0;
   1711 
   1712     //Load and read GPU library.
   1713     lib_surface_utils = NULL;
   1714     LINK_get_surface_pixel_alignment = NULL;
   1715     mSurfaceStridePadding = CAM_PAD_TO_32;
   1716     lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
   1717     if (lib_surface_utils) {
   1718         *(void **)&LINK_get_surface_pixel_alignment =
   1719                 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
   1720          if (LINK_get_surface_pixel_alignment) {
   1721              mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
   1722          }
   1723          dlclose(lib_surface_utils);
   1724     }
   1725 }
   1726 
   1727 /*===========================================================================
   1728  * FUNCTION   : ~QCamera2HardwareInterface
   1729  *
   1730  * DESCRIPTION: destructor of QCamera2HardwareInterface
   1731  *
   1732  * PARAMETERS : none
   1733  *
   1734  * RETURN     : none
   1735  *==========================================================================*/
   1736 QCamera2HardwareInterface::~QCamera2HardwareInterface()
   1737 {
   1738     LOGH("E");
   1739 
   1740     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
   1741     mDeferredWorkThread.exit();
   1742 
   1743     if (mMetadataMem != NULL) {
   1744         delete mMetadataMem;
   1745         mMetadataMem = NULL;
   1746     }
   1747 
   1748     m_perfLock.lock_acq();
   1749     lockAPI();
   1750     m_smThreadActive = false;
   1751     unlockAPI();
   1752     m_stateMachine.releaseThread();
   1753     closeCamera();
   1754     m_perfLock.lock_rel();
   1755     m_perfLock.lock_deinit();
   1756     pthread_mutex_destroy(&m_lock);
   1757     pthread_cond_destroy(&m_cond);
   1758     pthread_mutex_destroy(&m_evtLock);
   1759     pthread_cond_destroy(&m_evtCond);
   1760     pthread_mutex_destroy(&m_int_lock);
   1761     pthread_cond_destroy(&m_int_cond);
   1762     pthread_mutex_destroy(&mGrallocLock);
   1763     LOGH("X");
   1764 }
   1765 
   1766 /*===========================================================================
   1767  * FUNCTION   : deferPPInit
   1768  *
   1769  * DESCRIPTION: Queue postproc init task to deferred thread
   1770  *
   1771  * PARAMETERS : none
   1772  *
   1773  * RETURN     : uint32_t job id of pproc init job
   1774  *              0  -- failure
   1775  *==========================================================================*/
   1776 uint32_t QCamera2HardwareInterface::deferPPInit()
   1777 {
   1778     // init pproc
   1779     DeferWorkArgs args;
   1780     DeferPProcInitArgs pprocInitArgs;
   1781 
   1782     memset(&args, 0, sizeof(DeferWorkArgs));
   1783     memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
   1784 
   1785     pprocInitArgs.jpeg_cb = jpegEvtHandle;
   1786     pprocInitArgs.user_data = this;
   1787     args.pprocInitArgs = pprocInitArgs;
   1788 
   1789     return queueDeferredWork(CMD_DEF_PPROC_INIT,
   1790             args);
   1791 }
   1792 
   1793 /*===========================================================================
   1794  * FUNCTION   : openCamera
   1795  *
   1796  * DESCRIPTION: open camera
   1797  *
   1798  * PARAMETERS :
   1799  *   @hw_device  : double ptr for camera device struct
   1800  *
   1801  * RETURN     : int32_t type of status
   1802  *              NO_ERROR  -- success
   1803  *              none-zero failure code
   1804  *==========================================================================*/
   1805 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
   1806 {
   1807     KPI_ATRACE_CALL();
   1808     int rc = NO_ERROR;
   1809     if (mCameraOpened) {
   1810         *hw_device = NULL;
   1811         LOGE("Permission Denied");
   1812         return PERMISSION_DENIED;
   1813     }
   1814     LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
   1815             mCameraId);
   1816     m_perfLock.lock_acq_timed(CAMERA_OPEN_PERF_TIME_OUT);
   1817     rc = openCamera();
   1818     if (rc == NO_ERROR){
   1819         *hw_device = &mCameraDevice.common;
   1820         if (m_thermalAdapter.init(this) != 0) {
   1821           LOGW("Init thermal adapter failed");
   1822         }
   1823     }
   1824     else
   1825         *hw_device = NULL;
   1826 
   1827     LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
   1828             mCameraId, rc);
   1829 
   1830     return rc;
   1831 }
   1832 
   1833 /*===========================================================================
   1834  * FUNCTION   : openCamera
   1835  *
   1836  * DESCRIPTION: open camera
   1837  *
   1838  * PARAMETERS : none
   1839  *
   1840  * RETURN     : int32_t type of status
   1841  *              NO_ERROR  -- success
   1842  *              none-zero failure code
   1843  *==========================================================================*/
   1844 int QCamera2HardwareInterface::openCamera()
   1845 {
   1846     int32_t rc = NO_ERROR;
   1847     char value[PROPERTY_VALUE_MAX];
   1848 
   1849     if (mCameraHandle) {
   1850         LOGE("Failure: Camera already opened");
   1851         return ALREADY_EXISTS;
   1852     }
   1853 
   1854     rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
   1855     if (rc < 0) {
   1856         LOGE("Failed to reserve flash for camera id: %d",
   1857                 mCameraId);
   1858         return UNKNOWN_ERROR;
   1859     }
   1860 
   1861     // alloc param buffer
   1862     DeferWorkArgs args;
   1863     memset(&args, 0, sizeof(args));
   1864     mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
   1865     if (mParamAllocJob == 0) {
   1866         LOGE("Failed queueing PARAM_ALLOC job");
   1867         return -ENOMEM;
   1868     }
   1869 
   1870     if (gCamCapability[mCameraId] != NULL) {
   1871         // allocate metadata buffers
   1872         DeferWorkArgs args;
   1873         DeferMetadataAllocArgs metadataAllocArgs;
   1874 
   1875         memset(&args, 0, sizeof(args));
   1876         memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
   1877 
   1878         uint32_t padding =
   1879                 gCamCapability[mCameraId]->padding_info.plane_padding;
   1880         metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
   1881                 padding);
   1882         metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
   1883         args.metadataAllocArgs = metadataAllocArgs;
   1884 
   1885         mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
   1886         if (mMetadataAllocJob == 0) {
   1887             LOGE("Failed to allocate metadata buffer");
   1888             rc = -ENOMEM;
   1889             goto error_exit1;
   1890         }
   1891 
   1892         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
   1893         if (rc) {
   1894             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
   1895                      rc, mCameraHandle);
   1896             goto error_exit2;
   1897         }
   1898 
   1899         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
   1900                 camEvtHandle,
   1901                 (void *) this);
   1902     } else {
   1903         LOGH("Capabilities not inited, initializing now.");
   1904 
   1905         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
   1906         if (rc) {
   1907             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
   1908                      rc, mCameraHandle);
   1909             goto error_exit2;
   1910         }
   1911 
   1912         if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
   1913             LOGE("initCapabilities failed.");
   1914             rc = UNKNOWN_ERROR;
   1915             goto error_exit3;
   1916         }
   1917 
   1918         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
   1919                 camEvtHandle,
   1920                 (void *) this);
   1921     }
   1922 
   1923     // Init params in the background
   1924     // 1. It's safe to queue init job, even if alloc job is not yet complete.
   1925     // It will be queued to the same thread, so the alloc is guaranteed to
   1926     // finish first.
   1927     // 2. However, it is not safe to begin param init until after camera is
   1928     // open. That is why we wait until after camera open completes to schedule
   1929     // this task.
   1930     memset(&args, 0, sizeof(args));
   1931     mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
   1932     if (mParamInitJob == 0) {
   1933         LOGE("Failed queuing PARAM_INIT job");
   1934         rc = -ENOMEM;
   1935         goto error_exit3;
   1936     }
   1937 
   1938     mCameraOpened = true;
   1939 
   1940     //Notify display HAL that a camera session is active.
   1941     //But avoid calling the same during bootup because camera service might open/close
   1942     //cameras at boot time during its initialization and display service will also internally
   1943     //wait for camera service to initialize first while calling this display API, resulting in a
   1944     //deadlock situation. Since boot time camera open/close calls are made only to fetch
   1945     //capabilities, no need of this display bw optimization.
   1946     //Use "service.bootanim.exit" property to know boot status.
   1947     property_get("service.bootanim.exit", value, "0");
   1948     if (atoi(value) == 1) {
   1949         pthread_mutex_lock(&gCamLock);
   1950         if (gNumCameraSessions++ == 0) {
   1951             setCameraLaunchStatus(true);
   1952         }
   1953         pthread_mutex_unlock(&gCamLock);
   1954     }
   1955 
   1956     return NO_ERROR;
   1957 
   1958 error_exit3:
   1959     if(mJpegClientHandle) {
   1960         deinitJpegHandle();
   1961     }
   1962     mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
   1963     mCameraHandle = NULL;
   1964 error_exit2:
   1965     waitDeferredWork(mMetadataAllocJob);
   1966 error_exit1:
   1967     waitDeferredWork(mParamAllocJob);
   1968     return rc;
   1969 
   1970 }
   1971 
   1972 /*===========================================================================
   1973  * FUNCTION   : bundleRelatedCameras
   1974  *
   1975  * DESCRIPTION: bundle cameras to enable syncing of cameras
   1976  *
   1977  * PARAMETERS :
   1978  *   @sync        :indicates whether syncing is On or Off
   1979  *   @sessionid  :session id for other camera session
   1980  *
   1981  * RETURN     : int32_t type of status
   1982  *              NO_ERROR  -- success
   1983  *              none-zero failure code
   1984  *==========================================================================*/
   1985 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn,
   1986             uint32_t sessionid)
   1987 {
   1988     LOGD("bundleRelatedCameras sync %d with sessionid %d",
   1989             syncOn, sessionid);
   1990 
   1991     int32_t rc = mParameters.bundleRelatedCameras(syncOn, sessionid);
   1992     if (rc != NO_ERROR) {
   1993         LOGE("bundleRelatedCameras failed %d", rc);
   1994         return rc;
   1995     }
   1996     return rc;
   1997 }
   1998 
   1999 /*===========================================================================
   2000  * FUNCTION   : getCameraSessionId
   2001  *
   2002  * DESCRIPTION: gets the backend session Id of this HWI instance
   2003  *
   2004  * PARAMETERS :
   2005  *   @sessionid  : pointer to the output session id
   2006  *
   2007  * RETURN     : int32_t type of status
   2008  *              NO_ERROR  -- success
   2009  *              none-zero failure code
   2010  *==========================================================================*/
   2011 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
   2012 {
   2013     int32_t rc = NO_ERROR;
   2014 
   2015     if(session_id != NULL) {
   2016         rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
   2017                 session_id);
   2018         LOGD("Getting Camera Session Id %d", *session_id);
   2019     } else {
   2020         LOGE("Session Id is Null");
   2021         return UNKNOWN_ERROR;
   2022     }
   2023     return rc;
   2024 }
   2025 
   2026 /*===========================================================================
   2027  * FUNCTION   : getRelatedCamSyncInfo
   2028  *
   2029  * DESCRIPTION:returns the related cam sync info for this HWI instance
   2030  *
   2031  * PARAMETERS :none
   2032  *
   2033  * RETURN     : const pointer to cam_sync_related_sensors_event_info_t
   2034  *==========================================================================*/
   2035 const cam_sync_related_sensors_event_info_t*
   2036         QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
   2037 {
   2038     return mParameters.getRelatedCamSyncInfo();
   2039 }
   2040 
   2041 /*===========================================================================
   2042  * FUNCTION   : setRelatedCamSyncInfo
   2043  *
   2044  * DESCRIPTION:sets the related cam sync info for this HWI instance
   2045  *
   2046  * PARAMETERS :
   2047  *   @info  : ptr to related cam info parameters
   2048  *
   2049  * RETURN     : int32_t type of status
   2050  *              NO_ERROR  -- success
   2051  *              none-zero failure code
   2052  *==========================================================================*/
   2053 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
   2054         cam_sync_related_sensors_event_info_t* info)
   2055 {
   2056     if(info) {
   2057         return mParameters.setRelatedCamSyncInfo(info);
   2058     } else {
   2059         return BAD_TYPE;
   2060     }
   2061 }
   2062 
   2063 /*===========================================================================
   2064  * FUNCTION   : getMpoComposition
   2065  *
   2066  * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
   2067  *                    or not
   2068  *
   2069  * PARAMETERS :none
   2070  *
   2071  * RETURN     : bool indicates whether mpo composition is enabled or not
   2072  *==========================================================================*/
   2073 bool QCamera2HardwareInterface::getMpoComposition(void)
   2074 {
   2075     LOGH("MpoComposition:%d ", m_bMpoEnabled);
   2076     return m_bMpoEnabled;
   2077 }
   2078 
   2079 /*===========================================================================
   2080  * FUNCTION   : setMpoComposition
   2081  *
   2082  * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
   2083  *
   2084  * PARAMETERS :
   2085  *   @enable  : indicates whether Mpo composition enabled or not
   2086  *
   2087  * RETURN     : int32_t type of status
   2088  *              NO_ERROR  -- success
   2089  *              none-zero failure code
   2090  *==========================================================================*/
   2091 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
   2092 {
   2093     // By default set Mpo composition to disable
   2094     m_bMpoEnabled = false;
   2095 
   2096     // Enable Mpo composition only if
   2097     // 1) frame sync is ON between two cameras and
   2098     // 2) any advanced features are not enabled (AOST features) and
   2099     // 3) not in recording mode (for liveshot case)
   2100     // 4) flash is not needed
   2101     if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
   2102             !mParameters.isAdvCamFeaturesEnabled() &&
   2103             !mParameters.getRecordingHintValue() &&
   2104             !mFlashNeeded &&
   2105             !isLongshotEnabled()) {
   2106         m_bMpoEnabled = enable;
   2107         LOGH("MpoComposition:%d ", m_bMpoEnabled);
   2108         return NO_ERROR;
   2109     } else {
   2110         return BAD_TYPE;
   2111     }
   2112 }
   2113 
   2114 /*===========================================================================
   2115  * FUNCTION   : getRecordingHintValue
   2116  *
   2117  * DESCRIPTION:function to retrieve recording hint value
   2118  *
   2119  * PARAMETERS :none
   2120  *
   2121  * RETURN     : bool indicates whether recording hint is enabled or not
   2122  *==========================================================================*/
   2123 bool QCamera2HardwareInterface::getRecordingHintValue(void)
   2124 {
   2125     return mParameters.getRecordingHintValue();
   2126 }
   2127 
   2128 /*===========================================================================
   2129  * FUNCTION   : setRecordingHintValue
   2130  *
   2131  * DESCRIPTION:set recording hint value
   2132  *
   2133  * PARAMETERS :
   2134  *   @enable  : video hint value
   2135  *
   2136  * RETURN     : int32_t type of status
   2137  *              NO_ERROR  -- success
   2138  *              none-zero failure code
   2139  *==========================================================================*/
   2140 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
   2141 {
   2142     return mParameters.updateRecordingHintValue(value);
   2143 }
   2144 
   2145 /*===========================================================================
   2146  * FUNCTION   : closeCamera
   2147  *
   2148  * DESCRIPTION: close camera
   2149  *
   2150  * PARAMETERS : none
   2151  *
   2152  * RETURN     : int32_t type of status
   2153  *              NO_ERROR  -- success
   2154  *              none-zero failure code
   2155  *==========================================================================*/
   2156 int QCamera2HardwareInterface::closeCamera()
   2157 {
   2158     int rc = NO_ERROR;
   2159     int i;
   2160     char value[PROPERTY_VALUE_MAX];
   2161     LOGI("E");
   2162     if (!mCameraOpened) {
   2163         return NO_ERROR;
   2164     }
   2165     LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
   2166              mCameraId);
   2167 
   2168     // set open flag to false
   2169     mCameraOpened = false;
   2170 
   2171     // Reset Stream config info
   2172     mParameters.setStreamConfigure(false, false, true);
   2173 
   2174     // deinit Parameters
   2175     mParameters.deinit();
   2176 
   2177     // exit notifier
   2178     m_cbNotifier.exit();
   2179 
   2180     // stop and deinit postprocessor
   2181     waitDeferredWork(mReprocJob);
   2182     // Close the JPEG session
   2183     waitDeferredWork(mJpegJob);
   2184     m_postprocessor.stop();
   2185     deinitJpegHandle();
   2186     m_postprocessor.deinit();
   2187     mInitPProcJob = 0; // reset job id, so pproc can be reinited later
   2188 
   2189     m_thermalAdapter.deinit();
   2190 
   2191     // delete all channels if not already deleted
   2192     for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   2193         if (m_channels[i] != NULL) {
   2194             m_channels[i]->stop();
   2195             delete m_channels[i];
   2196             m_channels[i] = NULL;
   2197         }
   2198     }
   2199 
   2200     //free all pending api results here
   2201     if(m_apiResultList != NULL) {
   2202         api_result_list *apiResultList = m_apiResultList;
   2203         api_result_list *apiResultListNext;
   2204         while (apiResultList != NULL) {
   2205             apiResultListNext = apiResultList->next;
   2206             free(apiResultList);
   2207             apiResultList = apiResultListNext;
   2208         }
   2209     }
   2210 
   2211     rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
   2212     mCameraHandle = NULL;
   2213 
   2214     //Notify display HAL that there is no active camera session
   2215     //but avoid calling the same during bootup. Refer to openCamera
   2216     //for more details.
   2217     property_get("service.bootanim.exit", value, "0");
   2218     if (atoi(value) == 1) {
   2219         pthread_mutex_lock(&gCamLock);
   2220         if (--gNumCameraSessions == 0) {
   2221             setCameraLaunchStatus(false);
   2222         }
   2223         pthread_mutex_unlock(&gCamLock);
   2224     }
   2225 
   2226     if (mExifParams.debug_params) {
   2227         free(mExifParams.debug_params);
   2228         mExifParams.debug_params = NULL;
   2229     }
   2230 
   2231     if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
   2232         LOGD("Failed to release flash for camera id: %d",
   2233                 mCameraId);
   2234     }
   2235 
   2236     LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
   2237          mCameraId, rc);
   2238 
   2239     return rc;
   2240 }
   2241 
   2242 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
   2243 
   2244 /*===========================================================================
   2245  * FUNCTION   : initCapabilities
   2246  *
   2247  * DESCRIPTION: initialize camera capabilities in static data struct
   2248  *
   2249  * PARAMETERS :
   2250  *   @cameraId  : camera Id
   2251  *
   2252  * RETURN     : int32_t type of status
   2253  *              NO_ERROR  -- success
   2254  *              none-zero failure code
   2255  *==========================================================================*/
   2256 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
   2257         mm_camera_vtbl_t *cameraHandle)
   2258 {
   2259     ATRACE_CALL();
   2260     int rc = NO_ERROR;
   2261     QCameraHeapMemory *capabilityHeap = NULL;
   2262 
   2263     /* Allocate memory for capability buffer */
   2264     capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   2265     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
   2266     if(rc != OK) {
   2267         LOGE("No memory for cappability");
   2268         goto allocate_failed;
   2269     }
   2270 
   2271     /* Map memory for capability buffer */
   2272     memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
   2273 
   2274     cam_buf_map_type_list bufMapList;
   2275     rc = QCameraBufferMaps::makeSingletonBufMapList(
   2276             CAM_MAPPING_BUF_TYPE_CAPABILITY,
   2277             0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
   2278             0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
   2279             bufMapList);
   2280 
   2281     if (rc == NO_ERROR) {
   2282         rc = cameraHandle->ops->map_bufs(cameraHandle->camera_handle,
   2283                 &bufMapList);
   2284     }
   2285 
   2286     if(rc < 0) {
   2287         LOGE("failed to map capability buffer");
   2288         goto map_failed;
   2289     }
   2290 
   2291     /* Query Capability */
   2292     rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
   2293     if(rc < 0) {
   2294         LOGE("failed to query capability");
   2295         goto query_failed;
   2296     }
   2297     gCamCapability[cameraId] =
   2298             (cam_capability_t *)malloc(sizeof(cam_capability_t));
   2299 
   2300     if (!gCamCapability[cameraId]) {
   2301         LOGE("out of memory");
   2302         goto query_failed;
   2303     }
   2304     memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),
   2305                                         sizeof(cam_capability_t));
   2306     gCamCapability[cameraId]->analysis_padding_info.offset_info.offset_x = 0;
   2307     gCamCapability[cameraId]->analysis_padding_info.offset_info.offset_y = 0;
   2308 
   2309     rc = NO_ERROR;
   2310 
   2311 query_failed:
   2312     cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
   2313                             CAM_MAPPING_BUF_TYPE_CAPABILITY);
   2314 map_failed:
   2315     capabilityHeap->deallocate();
   2316     delete capabilityHeap;
   2317 allocate_failed:
   2318     return rc;
   2319 }
   2320 
   2321 /*===========================================================================
   2322  * FUNCTION   : getCapabilities
   2323  *
   2324  * DESCRIPTION: query camera capabilities
   2325  *
   2326  * PARAMETERS :
   2327  *   @cameraId  : camera Id
   2328  *   @info      : camera info struct to be filled in with camera capabilities
   2329  *
   2330  * RETURN     : int type of status
   2331  *              NO_ERROR  -- success
   2332  *              none-zero failure code
   2333  *==========================================================================*/
   2334 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
   2335         struct camera_info *info, cam_sync_type_t *p_cam_type)
   2336 {
   2337     ATRACE_CALL();
   2338     int rc = NO_ERROR;
   2339     struct  camera_info *p_info = NULL;
   2340     pthread_mutex_lock(&gCamLock);
   2341     p_info = get_cam_info(cameraId, p_cam_type);
   2342     p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
   2343     p_info->static_camera_characteristics = NULL;
   2344     memcpy(info, p_info, sizeof (struct camera_info));
   2345     pthread_mutex_unlock(&gCamLock);
   2346     return rc;
   2347 }
   2348 
   2349 /*===========================================================================
   2350  * FUNCTION   : getCamHalCapabilities
   2351  *
   2352  * DESCRIPTION: get the HAL capabilities structure
   2353  *
   2354  * PARAMETERS :
   2355  *   @cameraId  : camera Id
   2356  *
   2357  * RETURN     : capability structure of respective camera
   2358  *
   2359  *==========================================================================*/
   2360 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
   2361 {
   2362     return gCamCapability[mCameraId];
   2363 }
   2364 
   2365 /*===========================================================================
   2366  * FUNCTION   : getBufNumRequired
   2367  *
   2368  * DESCRIPTION: return number of stream buffers needed for given stream type
   2369  *
   2370  * PARAMETERS :
   2371  *   @stream_type  : type of stream
   2372  *
   2373  * RETURN     : number of buffers needed
   2374  *==========================================================================*/
   2375 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
   2376 {
   2377     int bufferCnt = 0;
   2378     int minCaptureBuffers = mParameters.getNumOfSnapshots();
   2379     char value[PROPERTY_VALUE_MAX];
   2380     bool raw_yuv = false;
   2381     int persist_cnt = 0;
   2382 
   2383     int zslQBuffers = mParameters.getZSLQueueDepth();
   2384 
   2385     int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
   2386                             CAMERA_MIN_JPEG_ENCODING_BUFFERS;
   2387 
   2388     int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
   2389                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2390                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2391                        mParameters.getNumOfExtraBuffersForImageProc() +
   2392                        EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2393 
   2394     int minUndequeCount = 0;
   2395     if (!isNoDisplayMode()) {
   2396         if(mPreviewWindow != NULL) {
   2397             if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
   2398                 != 0) {
   2399                 LOGW("get_min_undequeued_buffer_count  failed");
   2400                 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
   2401                 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
   2402                 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
   2403             }
   2404         } else {
   2405             //preview window might not be set at this point. So, query directly
   2406             //from BufferQueue implementation of gralloc buffers.
   2407             //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
   2408             //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
   2409             minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
   2410         }
   2411         if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
   2412             // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
   2413             // and so change the MACRO as per minUndequeCount
   2414             LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
   2415                      minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
   2416         }
   2417     }
   2418 
   2419     LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
   2420             "maxStreamBuf = %d minUndequeCount = %d",
   2421             minCaptureBuffers, zslQBuffers, minCircularBufNum,
   2422             maxStreamBuf, minUndequeCount);
   2423     // Get buffer count for the particular stream type
   2424     switch (stream_type) {
   2425     case CAM_STREAM_TYPE_PREVIEW:
   2426         {
   2427             if (mParameters.isZSLMode()) {
   2428                 // We need to add two extra streming buffers to add
   2429                 // flexibility in forming matched super buf in ZSL queue.
   2430                 // with number being 'zslQBuffers + minCircularBufNum'
   2431                 // we see preview buffers sometimes get dropped at CPP
   2432                 // and super buf is not forming in ZSL Q for long time.
   2433 
   2434                 bufferCnt = zslQBuffers + minCircularBufNum +
   2435                         mParameters.getNumOfExtraBuffersForImageProc() +
   2436                         mParameters.getNumOfExtraBuffersForPreview() +
   2437                         mParameters.getNumOfExtraHDRInBufsIfNeeded();
   2438             } else {
   2439                 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
   2440                         mParameters.getMaxUnmatchedFramesInQueue() +
   2441                         mParameters.getNumOfExtraBuffersForPreview();
   2442             }
   2443             // ISP allocates native preview buffers and so reducing same from HAL allocation
   2444             if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
   2445                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2446 
   2447             if (mParameters.getRecordingHintValue() == true)
   2448                 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2449 
   2450             // Add the display minUndequeCount count on top of camera requirement
   2451             bufferCnt += minUndequeCount;
   2452 
   2453             property_get("persist.camera.preview_yuv", value, "0");
   2454             persist_cnt = atoi(value);
   2455             if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2456                     && (bufferCnt < persist_cnt)) {
   2457                 bufferCnt = persist_cnt;
   2458             }
   2459         }
   2460         break;
   2461     case CAM_STREAM_TYPE_POSTVIEW:
   2462         {
   2463             bufferCnt = minCaptureBuffers +
   2464                         mParameters.getMaxUnmatchedFramesInQueue() +
   2465                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2466                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2467                         mParameters.getNumOfExtraBuffersForImageProc();
   2468 
   2469             if (bufferCnt > maxStreamBuf) {
   2470                 bufferCnt = maxStreamBuf;
   2471             }
   2472             bufferCnt += minUndequeCount;
   2473         }
   2474         break;
   2475     case CAM_STREAM_TYPE_SNAPSHOT:
   2476         {
   2477             if (mParameters.isZSLMode() || mLongshotEnabled) {
   2478                 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
   2479                         !mLongshotEnabled) {
   2480                     // Single ZSL snapshot case
   2481                     bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
   2482                             mParameters.getNumOfExtraBuffersForImageProc();
   2483                 }
   2484                 else {
   2485                     // ZSL Burst or Longshot case
   2486                     bufferCnt = zslQBuffers + minCircularBufNum +
   2487                             mParameters.getNumOfExtraBuffersForImageProc();
   2488                 }
   2489                 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
   2490                     //ISP allocates native buffers in YUV case
   2491                     bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2492                 }
   2493             } else {
   2494                 bufferCnt = minCaptureBuffers +
   2495                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2496                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2497                             mParameters.getNumOfExtraBuffersForImageProc();
   2498 
   2499                 if (bufferCnt > maxStreamBuf) {
   2500                     bufferCnt = maxStreamBuf;
   2501                 }
   2502             }
   2503         }
   2504         break;
   2505     case CAM_STREAM_TYPE_RAW:
   2506         property_get("persist.camera.raw_yuv", value, "0");
   2507         raw_yuv = atoi(value) > 0 ? true : false;
   2508 
   2509         if (isRdiMode() || raw_yuv) {
   2510             bufferCnt = zslQBuffers + minCircularBufNum;
   2511         } else if (mParameters.isZSLMode()) {
   2512             bufferCnt = zslQBuffers + minCircularBufNum;
   2513             if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
   2514                 //ISP allocates native buffers in YUV case
   2515                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2516             }
   2517 
   2518         } else {
   2519             bufferCnt = minCaptureBuffers +
   2520                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2521                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2522                         mParameters.getNumOfExtraBuffersForImageProc();
   2523 
   2524             if (bufferCnt > maxStreamBuf) {
   2525                 bufferCnt = maxStreamBuf;
   2526             }
   2527         }
   2528 
   2529         property_get("persist.camera.preview_raw", value, "0");
   2530         persist_cnt = atoi(value);
   2531         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2532                 && (bufferCnt < persist_cnt)) {
   2533             bufferCnt = persist_cnt;
   2534         }
   2535         property_get("persist.camera.video_raw", value, "0");
   2536         persist_cnt = atoi(value);
   2537         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2538                 && (bufferCnt < persist_cnt)) {
   2539             bufferCnt = persist_cnt;
   2540         }
   2541 
   2542         break;
   2543     case CAM_STREAM_TYPE_VIDEO:
   2544         {
   2545             if (mParameters.getBufBatchCount()) {
   2546                 //Video Buffer in case of HFR or camera batching..
   2547                 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
   2548             } else if (mParameters.getVideoBatchSize()) {
   2549                 //Video Buffer count only for HAL to HAL batching.
   2550                 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
   2551                         * mParameters.getVideoBatchSize());
   2552                 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
   2553                     bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
   2554                 }
   2555             } else {
   2556                 // No batching enabled.
   2557                 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
   2558             }
   2559 
   2560             bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
   2561             //if its 4K encoding usecase, then add extra buffer
   2562             cam_dimension_t dim;
   2563             mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
   2564             if (is4k2kResolution(&dim)) {
   2565                  //get additional buffer count
   2566                  property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
   2567                  bufferCnt += atoi(value);
   2568             }
   2569         }
   2570         break;
   2571     case CAM_STREAM_TYPE_METADATA:
   2572         {
   2573             if (mParameters.isZSLMode()) {
   2574                 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
   2575                 bufferCnt = zslQBuffers + minCircularBufNum +
   2576                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2577                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2578                             mParameters.getNumOfExtraBuffersForImageProc() +
   2579                             EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2580             } else {
   2581                 bufferCnt = minCaptureBuffers +
   2582                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2583                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2584                             mParameters.getMaxUnmatchedFramesInQueue() +
   2585                             CAMERA_MIN_STREAMING_BUFFERS +
   2586                             mParameters.getNumOfExtraBuffersForImageProc();
   2587 
   2588                 if (bufferCnt > zslQBuffers + minCircularBufNum) {
   2589                     bufferCnt = zslQBuffers + minCircularBufNum;
   2590                 }
   2591             }
   2592             if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
   2593                 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
   2594             }
   2595         }
   2596         break;
   2597     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2598         {
   2599             bufferCnt = minCaptureBuffers;
   2600             // One of the ubifocus buffers is miscellaneous buffer
   2601             if (mParameters.isUbiRefocus()) {
   2602                 bufferCnt -= 1;
   2603             }
   2604             if (mLongshotEnabled) {
   2605                 bufferCnt = mParameters.getLongshotStages();
   2606             }
   2607         }
   2608         break;
   2609     case CAM_STREAM_TYPE_CALLBACK:
   2610         bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
   2611         break;
   2612     case CAM_STREAM_TYPE_ANALYSIS:
   2613     case CAM_STREAM_TYPE_DEFAULT:
   2614     case CAM_STREAM_TYPE_MAX:
   2615     default:
   2616         bufferCnt = 0;
   2617         break;
   2618     }
   2619 
   2620     LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
   2621     if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
   2622         LOGW("Buffer count %d for stream type %d exceeds limit %d",
   2623                  bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
   2624         return CAM_MAX_NUM_BUFS_PER_STREAM;
   2625     }
   2626 
   2627     return (uint8_t)bufferCnt;
   2628 }
   2629 
   2630 /*===========================================================================
   2631  * FUNCTION   : allocateStreamBuf
   2632  *
   2633  * DESCRIPTION: alocate stream buffers
   2634  *
   2635  * PARAMETERS :
   2636  *   @stream_type  : type of stream
   2637  *   @size         : size of buffer
   2638  *   @stride       : stride of buffer
   2639  *   @scanline     : scanline of buffer
   2640  *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
   2641  *                   could be modified during allocation if more buffers needed
   2642  *
   2643  * RETURN     : ptr to a memory obj that holds stream buffers.
   2644  *              NULL if failed
   2645  *==========================================================================*/
   2646 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
   2647         cam_stream_type_t stream_type, size_t size, int stride, int scanline,
   2648         uint8_t &bufferCnt)
   2649 {
   2650     int rc = NO_ERROR;
   2651     QCameraMemory *mem = NULL;
   2652     bool bCachedMem = QCAMERA_ION_USE_CACHE;
   2653     bool bPoolMem = false;
   2654     char value[PROPERTY_VALUE_MAX];
   2655     property_get("persist.camera.mem.usepool", value, "1");
   2656     if (atoi(value) == 1) {
   2657         bPoolMem = true;
   2658     }
   2659 
   2660     // Allocate stream buffer memory object
   2661     switch (stream_type) {
   2662     case CAM_STREAM_TYPE_PREVIEW:
   2663         {
   2664             if (isNoDisplayMode()) {
   2665                 mem = new QCameraStreamMemory(mGetMemory,
   2666                         bCachedMem,
   2667                         (bPoolMem) ? &m_memoryPool : NULL,
   2668                         stream_type);
   2669             } else {
   2670                 cam_dimension_t dim;
   2671                 int minFPS, maxFPS;
   2672                 QCameraGrallocMemory *grallocMemory =
   2673                     new QCameraGrallocMemory(mGetMemory);
   2674 
   2675                 mParameters.getStreamDimension(stream_type, dim);
   2676                 /* we are interested only in maxfps here */
   2677                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   2678                 int usage = 0;
   2679                 if(mParameters.isUBWCEnabled()) {
   2680                     cam_format_t fmt;
   2681                     mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
   2682                     if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   2683                         usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
   2684                     }
   2685                 }
   2686                 if (grallocMemory) {
   2687                     grallocMemory->setMappable(
   2688                             CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
   2689                     grallocMemory->setWindowInfo(mPreviewWindow,
   2690                             dim.width,dim.height, stride, scanline,
   2691                             mParameters.getPreviewHalPixelFormat(),
   2692                             maxFPS, usage);
   2693                     pthread_mutex_lock(&mGrallocLock);
   2694                     if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
   2695                         mEnqueuedBuffers = (bufferCnt -
   2696                                 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
   2697                     } else {
   2698                         mEnqueuedBuffers = 0;
   2699                     }
   2700                     pthread_mutex_unlock(&mGrallocLock);
   2701                 }
   2702                 mem = grallocMemory;
   2703             }
   2704         }
   2705         break;
   2706     case CAM_STREAM_TYPE_POSTVIEW:
   2707         {
   2708             if (isNoDisplayMode() || isPreviewRestartEnabled()) {
   2709                 mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
   2710             } else {
   2711                 cam_dimension_t dim;
   2712                 int minFPS, maxFPS;
   2713                 QCameraGrallocMemory *grallocMemory =
   2714                         new QCameraGrallocMemory(mGetMemory);
   2715 
   2716                 mParameters.getStreamDimension(stream_type, dim);
   2717                 /* we are interested only in maxfps here */
   2718                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   2719                 if (grallocMemory) {
   2720                     grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
   2721                             dim.height, stride, scanline,
   2722                             mParameters.getPreviewHalPixelFormat(), maxFPS);
   2723                 }
   2724                 mem = grallocMemory;
   2725             }
   2726         }
   2727         break;
   2728     case CAM_STREAM_TYPE_ANALYSIS:
   2729     case CAM_STREAM_TYPE_SNAPSHOT:
   2730     case CAM_STREAM_TYPE_RAW:
   2731     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2732         mem = new QCameraStreamMemory(mGetMemory,
   2733                 bCachedMem,
   2734                 (bPoolMem) ? &m_memoryPool : NULL,
   2735                 stream_type);
   2736         break;
   2737     case CAM_STREAM_TYPE_METADATA:
   2738         {
   2739             if (mMetadataMem == NULL) {
   2740                 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
   2741             } else {
   2742                 mem = mMetadataMem;
   2743                 mMetadataMem = NULL;
   2744 
   2745                 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
   2746                 if (numAdditionalBuffers > 0) {
   2747                     rc = mem->allocateMore(numAdditionalBuffers, size);
   2748                     if (rc != NO_ERROR) {
   2749                         LOGE("Failed to allocate additional buffers, "
   2750                                 "but attempting to proceed.");
   2751                     }
   2752                 }
   2753                 bufferCnt = mem->getCnt();
   2754                 // The memory is already allocated  and initialized, so
   2755                 // simply return here.
   2756                 return mem;
   2757             }
   2758         }
   2759         break;
   2760     case CAM_STREAM_TYPE_VIDEO:
   2761         {
   2762             //Use uncached allocation by default
   2763             if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
   2764                     mParameters.isHighQualityNoiseReductionMode()) {
   2765                 bCachedMem = QCAMERA_ION_USE_CACHE;
   2766             }
   2767             else {
   2768                 bCachedMem = QCAMERA_ION_USE_NOCACHE;
   2769             }
   2770 
   2771             QCameraVideoMemory *videoMemory = NULL;
   2772             if (mParameters.getVideoBatchSize()) {
   2773                 videoMemory = new QCameraVideoMemory(
   2774                         mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
   2775                 if (videoMemory == NULL) {
   2776                     LOGE("Out of memory for video batching obj");
   2777                     return NULL;
   2778                 }
   2779                 /*
   2780                 *   numFDs = BATCH size
   2781                 *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
   2782                 */
   2783                 rc = videoMemory->allocateMeta(
   2784                         CAMERA_MIN_VIDEO_BATCH_BUFFERS,
   2785                         mParameters.getVideoBatchSize(),
   2786                         VIDEO_METADATA_NUM_INTS);
   2787                 if (rc < 0) {
   2788                     delete videoMemory;
   2789                     return NULL;
   2790                 }
   2791             } else {
   2792                 videoMemory =
   2793                         new QCameraVideoMemory(mGetMemory, bCachedMem);
   2794                 if (videoMemory == NULL) {
   2795                     LOGE("Out of memory for video obj");
   2796                     return NULL;
   2797                 }
   2798             }
   2799 
   2800             int usage = 0;
   2801             cam_format_t fmt;
   2802             mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
   2803             if (mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
   2804                 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   2805             }
   2806             videoMemory->setVideoInfo(usage, fmt);
   2807             mem = videoMemory;
   2808         }
   2809         break;
   2810     case CAM_STREAM_TYPE_CALLBACK:
   2811         mem = new QCameraStreamMemory(mGetMemory,
   2812                 bCachedMem,
   2813                 (bPoolMem) ? &m_memoryPool : NULL,
   2814                 stream_type);
   2815         break;
   2816     case CAM_STREAM_TYPE_DEFAULT:
   2817     case CAM_STREAM_TYPE_MAX:
   2818     default:
   2819         break;
   2820     }
   2821     if (!mem) {
   2822         return NULL;
   2823     }
   2824 
   2825     if (bufferCnt > 0) {
   2826         if (mParameters.isSecureMode() &&
   2827             (stream_type == CAM_STREAM_TYPE_RAW) &&
   2828             (mParameters.isRdiMode())) {
   2829             LOGD("Allocating %d secure buffers of size %d ", bufferCnt, size);
   2830             rc = mem->allocate(bufferCnt, size, SECURE);
   2831         } else {
   2832             rc = mem->allocate(bufferCnt, size, NON_SECURE);
   2833         }
   2834         if (rc < 0) {
   2835             delete mem;
   2836             return NULL;
   2837         }
   2838         bufferCnt = mem->getCnt();
   2839     }
   2840     LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d",
   2841             rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem);
   2842     return mem;
   2843 }
   2844 
   2845 /*===========================================================================
   2846  * FUNCTION   : allocateMoreStreamBuf
   2847  *
   2848  * DESCRIPTION: alocate more stream buffers from the memory object
   2849  *
   2850  * PARAMETERS :
   2851  *   @mem_obj      : memory object ptr
   2852  *   @size         : size of buffer
   2853  *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
   2854  *                   output will be the number of total buffers
   2855  *
   2856  * RETURN     : int32_t type of status
   2857  *              NO_ERROR  -- success
   2858  *              none-zero failure code
   2859  *==========================================================================*/
   2860 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
   2861         QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
   2862 {
   2863     int rc = NO_ERROR;
   2864 
   2865     if (bufferCnt > 0) {
   2866         rc = mem_obj->allocateMore(bufferCnt, size);
   2867         bufferCnt = mem_obj->getCnt();
   2868     }
   2869     return rc;
   2870 }
   2871 
   2872 /*===========================================================================
   2873  * FUNCTION   : allocateMiscBuf
   2874  *
   2875  * DESCRIPTION: alocate miscellaneous buffer
   2876  *
   2877  * PARAMETERS :
   2878  *   @streamInfo  : stream info
   2879  *
   2880  * RETURN     : ptr to a memory obj that holds stream info buffer.
   2881  *              NULL if failed
   2882  *==========================================================================*/
   2883 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
   2884         cam_stream_info_t *streamInfo)
   2885 {
   2886     int rc = NO_ERROR;
   2887     uint8_t bufNum = 0;
   2888     size_t bufSize = 0;
   2889     QCameraHeapMemory *miscBuf = NULL;
   2890     uint32_t feature_mask =
   2891             streamInfo->reprocess_config.pp_feature_config.feature_mask;
   2892 
   2893     switch (streamInfo->stream_type) {
   2894     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2895         if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
   2896             bufNum = 1;
   2897             bufSize = mParameters.getTPMaxMetaSize();
   2898         } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
   2899             bufNum = 1;
   2900             bufSize = mParameters.getRefocusMaxMetaSize();
   2901         }
   2902         break;
   2903     default:
   2904         break;
   2905     }
   2906 
   2907     if (bufNum && bufSize) {
   2908         miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   2909 
   2910         if (!miscBuf) {
   2911             LOGE("Unable to allocate miscBuf object");
   2912             return NULL;
   2913         }
   2914 
   2915         rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE);
   2916         if (rc < 0) {
   2917             LOGE("Failed to allocate misc buffer memory");
   2918             delete miscBuf;
   2919             return NULL;
   2920         }
   2921     }
   2922 
   2923     return miscBuf;
   2924 }
   2925 
   2926 /*===========================================================================
   2927  * FUNCTION   : allocateStreamInfoBuf
   2928  *
   2929  * DESCRIPTION: alocate stream info buffer
   2930  *
   2931  * PARAMETERS :
   2932  *   @stream_type  : type of stream
   2933  *
   2934  * RETURN     : ptr to a memory obj that holds stream info buffer.
   2935  *              NULL if failed
   2936  *==========================================================================*/
   2937 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
   2938         cam_stream_type_t stream_type)
   2939 {
   2940     int rc = NO_ERROR;
   2941     char value[PROPERTY_VALUE_MAX];
   2942     bool raw_yuv = false;
   2943 
   2944     QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   2945     if (!streamInfoBuf) {
   2946         LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
   2947         return NULL;
   2948     }
   2949 
   2950     rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE);
   2951     if (rc < 0) {
   2952         LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
   2953         delete streamInfoBuf;
   2954         return NULL;
   2955     }
   2956 
   2957     cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
   2958     memset(streamInfo, 0, sizeof(cam_stream_info_t));
   2959     streamInfo->stream_type = stream_type;
   2960     rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
   2961     rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
   2962     rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
   2963     streamInfo->num_bufs = getBufNumRequired(stream_type);
   2964     streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   2965     streamInfo->is_secure = NON_SECURE;
   2966 
   2967     switch (stream_type) {
   2968     case CAM_STREAM_TYPE_SNAPSHOT:
   2969         if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
   2970             mLongshotEnabled) {
   2971             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   2972         } else {
   2973             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   2974             streamInfo->num_of_burst = (uint8_t)
   2975                     (mParameters.getNumOfSnapshots()
   2976                         + mParameters.getNumOfExtraHDRInBufsIfNeeded()
   2977                         - mParameters.getNumOfExtraHDROutBufsIfNeeded()
   2978                         + mParameters.getNumOfExtraBuffersForImageProc());
   2979         }
   2980         break;
   2981     case CAM_STREAM_TYPE_RAW:
   2982         property_get("persist.camera.raw_yuv", value, "0");
   2983         raw_yuv = atoi(value) > 0 ? true : false;
   2984         if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) {
   2985             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   2986         } else {
   2987             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   2988             streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
   2989         }
   2990         if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
   2991             streamInfo->is_secure = SECURE;
   2992         } else {
   2993             streamInfo->is_secure = NON_SECURE;
   2994         }
   2995         break;
   2996     case CAM_STREAM_TYPE_POSTVIEW:
   2997         if (mLongshotEnabled) {
   2998             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   2999         } else {
   3000             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   3001             streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
   3002                 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
   3003                 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
   3004                 + mParameters.getNumOfExtraBuffersForImageProc());
   3005         }
   3006         break;
   3007     case CAM_STREAM_TYPE_VIDEO:
   3008         streamInfo->dis_enable = mParameters.isDISEnabled();
   3009         if (mParameters.getBufBatchCount()) {
   3010             //Update stream info structure with batch mode info
   3011             streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
   3012             streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
   3013             streamInfo->user_buf_info.size =
   3014                     (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
   3015             cam_fps_range_t pFpsRange;
   3016             mParameters.getHfrFps(pFpsRange);
   3017             streamInfo->user_buf_info.frameInterval =
   3018                     (long)((1000/pFpsRange.video_max_fps) * 1000);
   3019             LOGH("Video Batch Count = %d, interval = %d",
   3020                     streamInfo->user_buf_info.frame_buf_cnt,
   3021                     streamInfo->user_buf_info.frameInterval);
   3022         }
   3023     case CAM_STREAM_TYPE_PREVIEW:
   3024         if (mParameters.getRecordingHintValue()) {
   3025             if(mParameters.isDISEnabled()) {
   3026                 streamInfo->is_type = mParameters.getISType();
   3027             } else {
   3028                 streamInfo->is_type = IS_TYPE_NONE;
   3029             }
   3030         }
   3031         if (mParameters.isSecureMode()) {
   3032             streamInfo->is_secure = SECURE;
   3033         }
   3034         break;
   3035     case CAM_STREAM_TYPE_ANALYSIS:
   3036         streamInfo->noFrameExpected = 1;
   3037         break;
   3038     default:
   3039         break;
   3040     }
   3041 
   3042     // Update feature mask
   3043     mParameters.updatePpFeatureMask(stream_type);
   3044 
   3045     // Get feature mask
   3046     mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
   3047 
   3048     // Update pp config
   3049     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
   3050         int flipMode = mParameters.getFlipMode(stream_type);
   3051         if (flipMode > 0) {
   3052             streamInfo->pp_config.flip = (uint32_t)flipMode;
   3053         }
   3054     }
   3055     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
   3056         streamInfo->pp_config.sharpness = mParameters.getSharpness();
   3057     }
   3058     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
   3059         streamInfo->pp_config.effect = mParameters.getEffectValue();
   3060     }
   3061 
   3062     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
   3063         streamInfo->pp_config.denoise2d.denoise_enable = 1;
   3064         streamInfo->pp_config.denoise2d.process_plates =
   3065                 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
   3066     }
   3067 
   3068     if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
   3069             CAM_STREAM_TYPE_RAW == stream_type))) {
   3070         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
   3071                 CAM_QCOM_FEATURE_CROP)
   3072             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   3073         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
   3074                 CAM_QCOM_FEATURE_SCALE)
   3075             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   3076     }
   3077 
   3078     LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x\n",
   3079            stream_type, streamInfo->fmt, streamInfo->dim.width,
   3080            streamInfo->dim.height, streamInfo->num_bufs,
   3081            streamInfo->pp_config.feature_mask);
   3082 
   3083     return streamInfoBuf;
   3084 }
   3085 
   3086 /*===========================================================================
   3087  * FUNCTION   : allocateStreamUserBuf
   3088  *
   3089  * DESCRIPTION: allocate user ptr for stream buffers
   3090  *
   3091  * PARAMETERS :
   3092  *   @streamInfo  : stream info structure
   3093  *
   3094  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3095  *                    NULL if failed
   3096 
   3097  *==========================================================================*/
   3098 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
   3099         cam_stream_info_t *streamInfo)
   3100 {
   3101     int rc = NO_ERROR;
   3102     QCameraMemory *mem = NULL;
   3103     int size = 0;
   3104 
   3105     if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
   3106         LOGE("Stream is not in BATCH mode. Invalid Stream");
   3107         return NULL;
   3108     }
   3109 
   3110     // Allocate stream user buffer memory object
   3111     switch (streamInfo->stream_type) {
   3112     case CAM_STREAM_TYPE_VIDEO: {
   3113         QCameraVideoMemory *video_mem = new QCameraVideoMemory(
   3114                 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
   3115         if (video_mem == NULL) {
   3116             LOGE("Out of memory for video obj");
   3117             return NULL;
   3118         }
   3119         /*
   3120         *   numFDs = BATCH size
   3121         *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
   3122         */
   3123         rc = video_mem->allocateMeta(streamInfo->num_bufs,
   3124                 mParameters.getBufBatchCount(), VIDEO_METADATA_NUM_INTS);
   3125         if (rc < 0) {
   3126             LOGE("allocateMeta failed");
   3127             delete video_mem;
   3128             return NULL;
   3129         }
   3130         int usage = 0;
   3131         cam_format_t fmt;
   3132         mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
   3133         if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
   3134             usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   3135         }
   3136         video_mem->setVideoInfo(usage, fmt);
   3137         mem = static_cast<QCameraMemory *>(video_mem);
   3138     }
   3139     break;
   3140 
   3141     case CAM_STREAM_TYPE_PREVIEW:
   3142     case CAM_STREAM_TYPE_POSTVIEW:
   3143     case CAM_STREAM_TYPE_ANALYSIS:
   3144     case CAM_STREAM_TYPE_SNAPSHOT:
   3145     case CAM_STREAM_TYPE_RAW:
   3146     case CAM_STREAM_TYPE_METADATA:
   3147     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3148     case CAM_STREAM_TYPE_CALLBACK:
   3149         LOGE("Stream type Not supported.for BATCH processing");
   3150     break;
   3151 
   3152     case CAM_STREAM_TYPE_DEFAULT:
   3153     case CAM_STREAM_TYPE_MAX:
   3154     default:
   3155         break;
   3156     }
   3157     if (!mem) {
   3158         LOGE("Failed to allocate mem");
   3159         return NULL;
   3160     }
   3161 
   3162     /*Size of this buffer will be number of batch buffer */
   3163     size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
   3164             CAM_PAD_TO_4K);
   3165 
   3166     LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
   3167 
   3168     if (size > 0) {
   3169         // Allocating one buffer for all batch buffers
   3170         rc = mem->allocate(1, size, NON_SECURE);
   3171         if (rc < 0) {
   3172             delete mem;
   3173             return NULL;
   3174         }
   3175     }
   3176     return mem;
   3177 }
   3178 
   3179 
   3180 /*===========================================================================
   3181  * FUNCTION   : waitForDeferredAlloc
   3182  *
   3183  * DESCRIPTION: Wait for deferred allocation, if applicable
   3184  *              (applicable only for metadata buffers so far)
   3185  *
   3186  * PARAMETERS :
   3187  *   @stream_type  : type of stream to (possibly) wait for
   3188  *
   3189  * RETURN     : None
   3190  *==========================================================================*/
   3191 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
   3192 {
   3193     if (stream_type == CAM_STREAM_TYPE_METADATA) {
   3194         waitDeferredWork(mMetadataAllocJob);
   3195     }
   3196 }
   3197 
   3198 
   3199 /*===========================================================================
   3200  * FUNCTION   : setPreviewWindow
   3201  *
   3202  * DESCRIPTION: set preview window impl
   3203  *
   3204  * PARAMETERS :
   3205  *   @window  : ptr to window ops table struct
   3206  *
   3207  * RETURN     : int32_t type of status
   3208  *              NO_ERROR  -- success
   3209  *              none-zero failure code
   3210  *==========================================================================*/
   3211 int QCamera2HardwareInterface::setPreviewWindow(
   3212         struct preview_stream_ops *window)
   3213 {
   3214     mPreviewWindow = window;
   3215     return NO_ERROR;
   3216 }
   3217 
   3218 /*===========================================================================
   3219  * FUNCTION   : setCallBacks
   3220  *
   3221  * DESCRIPTION: set callbacks impl
   3222  *
   3223  * PARAMETERS :
   3224  *   @notify_cb  : notify cb
   3225  *   @data_cb    : data cb
   3226  *   @data_cb_timestamp : data cb with time stamp
   3227  *   @get_memory : request memory ops table
   3228  *   @user       : user data ptr
   3229  *
   3230  * RETURN     : int32_t type of status
   3231  *              NO_ERROR  -- success
   3232  *              none-zero failure code
   3233  *==========================================================================*/
   3234 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
   3235                                             camera_data_callback data_cb,
   3236                                             camera_data_timestamp_callback data_cb_timestamp,
   3237                                             camera_request_memory get_memory,
   3238                                             void *user)
   3239 {
   3240     mNotifyCb        = notify_cb;
   3241     mDataCb          = data_cb;
   3242     mDataCbTimestamp = data_cb_timestamp;
   3243     mGetMemory       = get_memory;
   3244     mCallbackCookie  = user;
   3245     m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
   3246     return NO_ERROR;
   3247 }
   3248 
   3249 /*===========================================================================
   3250  * FUNCTION   : setJpegCallBacks
   3251  *
   3252  * DESCRIPTION: set JPEG callbacks impl
   3253  *
   3254  * PARAMETERS :
   3255  *   @jpegCb  : Jpeg callback method
   3256  *   @callbackCookie    : callback cookie
   3257  *
   3258  * RETURN     : int32_t type of status
   3259  *              NO_ERROR  -- success
   3260  *              none-zero failure code
   3261  *==========================================================================*/
   3262 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
   3263                                             void *callbackCookie)
   3264 {
   3265     LOGH("camera id %d", getCameraId());
   3266     mJpegCb        = jpegCb;
   3267     mJpegCallbackCookie  = callbackCookie;
   3268     m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
   3269 }
   3270 
   3271 /*===========================================================================
   3272  * FUNCTION   : enableMsgType
   3273  *
   3274  * DESCRIPTION: enable msg type impl
   3275  *
   3276  * PARAMETERS :
   3277  *   @msg_type  : msg type mask to be enabled
   3278  *
   3279  * RETURN     : int32_t type of status
   3280  *              NO_ERROR  -- success
   3281  *              none-zero failure code
   3282  *==========================================================================*/
   3283 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
   3284 {
   3285     int32_t rc = NO_ERROR;
   3286 
   3287     if (mParameters.isUBWCEnabled()) {
   3288         /*Need Special CALLBACK stream incase application requesting for
   3289               Preview callback  in UBWC case*/
   3290         if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
   3291                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
   3292             if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
   3293                 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
   3294                 if (rc != NO_ERROR) {
   3295                     LOGE("START Callback Channel failed");
   3296                 }
   3297             }
   3298         }
   3299     }
   3300     mMsgEnabled |= msg_type;
   3301     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
   3302     return rc;
   3303 }
   3304 
   3305 /*===========================================================================
   3306  * FUNCTION   : disableMsgType
   3307  *
   3308  * DESCRIPTION: disable msg type impl
   3309  *
   3310  * PARAMETERS :
   3311  *   @msg_type  : msg type mask to be disabled
   3312  *
   3313  * RETURN     : int32_t type of status
   3314  *              NO_ERROR  -- success
   3315  *              none-zero failure code
   3316  *==========================================================================*/
   3317 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
   3318 {
   3319     int32_t rc = NO_ERROR;
   3320 
   3321     if (mParameters.isUBWCEnabled()) {
   3322         /*STOP CALLBACK STREAM*/
   3323         if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
   3324                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
   3325             if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
   3326                 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
   3327                 if (rc != NO_ERROR) {
   3328                     LOGE("STOP Callback Channel failed");
   3329                 }
   3330             }
   3331         }
   3332     }
   3333     mMsgEnabled &= ~msg_type;
   3334     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
   3335     return rc;
   3336 }
   3337 
   3338 /*===========================================================================
   3339  * FUNCTION   : msgTypeEnabled
   3340  *
   3341  * DESCRIPTION: impl to determine if certain msg_type is enabled
   3342  *
   3343  * PARAMETERS :
   3344  *   @msg_type  : msg type mask
   3345  *
   3346  * RETURN     : 0 -- not enabled
   3347  *              none 0 -- enabled
   3348  *==========================================================================*/
   3349 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
   3350 {
   3351     return (mMsgEnabled & msg_type);
   3352 }
   3353 
   3354 /*===========================================================================
   3355  * FUNCTION   : msgTypeEnabledWithLock
   3356  *
   3357  * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
   3358  *
   3359  * PARAMETERS :
   3360  *   @msg_type  : msg type mask
   3361  *
   3362  * RETURN     : 0 -- not enabled
   3363  *              none 0 -- enabled
   3364  *==========================================================================*/
   3365 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
   3366 {
   3367     int enabled = 0;
   3368     lockAPI();
   3369     enabled = mMsgEnabled & msg_type;
   3370     unlockAPI();
   3371     return enabled;
   3372 }
   3373 
   3374 /*===========================================================================
   3375  * FUNCTION   : startPreview
   3376  *
   3377  * DESCRIPTION: start preview impl
   3378  *
   3379  * PARAMETERS : none
   3380  *
   3381  * RETURN     : int32_t type of status
   3382  *              NO_ERROR  -- success
   3383  *              none-zero failure code
   3384  *==========================================================================*/
   3385 int QCamera2HardwareInterface::startPreview()
   3386 {
   3387     KPI_ATRACE_CALL();
   3388     int32_t rc = NO_ERROR;
   3389 
   3390     LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
   3391             mParameters.getRecordingHintValue());
   3392 
   3393     m_perfLock.lock_acq();
   3394 
   3395     updateThermalLevel((void *)&mThermalLevel);
   3396 
   3397     setDisplayFrameSkip();
   3398 
   3399     // start preview stream
   3400     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
   3401         rc = startChannel(QCAMERA_CH_TYPE_ZSL);
   3402     } else {
   3403         rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
   3404     }
   3405 
   3406     if (rc != NO_ERROR) {
   3407         LOGE("failed to start channels");
   3408         m_perfLock.lock_rel();
   3409         return rc;
   3410     }
   3411 
   3412     if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
   3413             && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
   3414         rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
   3415         if (rc != NO_ERROR) {
   3416             LOGE("failed to start callback stream");
   3417             stopChannel(QCAMERA_CH_TYPE_ZSL);
   3418             stopChannel(QCAMERA_CH_TYPE_PREVIEW);
   3419             m_perfLock.lock_rel();
   3420             return rc;
   3421         }
   3422     }
   3423 
   3424     updatePostPreviewParameters();
   3425     m_stateMachine.setPreviewCallbackNeeded(true);
   3426 
   3427     // if job id is non-zero, that means the postproc init job is already
   3428     // pending or complete
   3429     if (mInitPProcJob == 0) {
   3430         mInitPProcJob = deferPPInit();
   3431         if (mInitPProcJob == 0) {
   3432             LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
   3433                      mCameraHandle);
   3434             rc = -ENOMEM;
   3435             m_perfLock.lock_rel();
   3436             return rc;
   3437         }
   3438     }
   3439     m_perfLock.lock_rel();
   3440 
   3441     if (rc == NO_ERROR) {
   3442         // Set power Hint for preview
   3443         m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
   3444     }
   3445 
   3446     LOGI("X rc = %d", rc);
   3447     return rc;
   3448 }
   3449 
   3450 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
   3451     // Enable OIS only in Camera mode and 4k2k camcoder mode
   3452     int32_t rc = NO_ERROR;
   3453     rc = mParameters.updateOisValue(1);
   3454     return NO_ERROR;
   3455 }
   3456 
   3457 /*===========================================================================
   3458  * FUNCTION   : stopPreview
   3459  *
   3460  * DESCRIPTION: stop preview impl
   3461  *
   3462  * PARAMETERS : none
   3463  *
   3464  * RETURN     : int32_t type of status
   3465  *              NO_ERROR  -- success
   3466  *              none-zero failure code
   3467  *==========================================================================*/
   3468 int QCamera2HardwareInterface::stopPreview()
   3469 {
   3470     KPI_ATRACE_CALL();
   3471     LOGI("E");
   3472     mNumPreviewFaces = -1;
   3473     mActiveAF = false;
   3474 
   3475     // Disable power Hint for preview
   3476     m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
   3477 
   3478     m_perfLock.lock_acq();
   3479 
   3480     // stop preview stream
   3481     stopChannel(QCAMERA_CH_TYPE_CALLBACK);
   3482     stopChannel(QCAMERA_CH_TYPE_ZSL);
   3483     stopChannel(QCAMERA_CH_TYPE_PREVIEW);
   3484     stopChannel(QCAMERA_CH_TYPE_RAW);
   3485 
   3486     m_cbNotifier.flushPreviewNotifications();
   3487     //add for ts makeup
   3488 #ifdef TARGET_TS_MAKEUP
   3489     ts_makeup_finish();
   3490 #endif
   3491     // delete all channels from preparePreview
   3492     unpreparePreview();
   3493 
   3494     m_perfLock.lock_rel();
   3495 
   3496     LOGI("X");
   3497     return NO_ERROR;
   3498 }
   3499 
   3500 /*===========================================================================
   3501  * FUNCTION   : storeMetaDataInBuffers
   3502  *
   3503  * DESCRIPTION: enable store meta data in buffers for video frames impl
   3504  *
   3505  * PARAMETERS :
   3506  *   @enable  : flag if need enable
   3507  *
   3508  * RETURN     : int32_t type of status
   3509  *              NO_ERROR  -- success
   3510  *              none-zero failure code
   3511  *==========================================================================*/
   3512 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
   3513 {
   3514     mStoreMetaDataInFrame = enable;
   3515     return NO_ERROR;
   3516 }
   3517 
   3518 /*===========================================================================
   3519  * FUNCTION   : preStartRecording
   3520  *
   3521  * DESCRIPTION: Prepare start recording impl
   3522  *
   3523  * PARAMETERS : none
   3524  *
   3525  * RETURN     : int32_t type of status
   3526  *              NO_ERROR  -- success
   3527  *              none-zero failure code
   3528  *==========================================================================*/
   3529 int QCamera2HardwareInterface::preStartRecording()
   3530 {
   3531     int32_t rc = NO_ERROR;
   3532     LOGH("E");
   3533     if (mParameters.getRecordingHintValue() == false) {
   3534 
   3535         // Give HWI control to restart preview only in single camera mode.
   3536         // In dual-cam mode, this control belongs to muxer.
   3537         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   3538             LOGH("start recording when hint is false, stop preview first");
   3539             stopPreview();
   3540 
   3541             // Set recording hint to TRUE
   3542             mParameters.updateRecordingHintValue(TRUE);
   3543             rc = preparePreview();
   3544             if (rc == NO_ERROR) {
   3545                 rc = startPreview();
   3546             }
   3547         }
   3548         else
   3549         {
   3550             // For dual cam mode, update the flag mPreviewRestartNeeded to true
   3551             // Restart control will be handled by muxer.
   3552             mPreviewRestartNeeded = true;
   3553         }
   3554     }
   3555 
   3556     LOGH("X rc = %d", rc);
   3557     return rc;
   3558 }
   3559 
   3560 /*===========================================================================
   3561  * FUNCTION   : startRecording
   3562  *
   3563  * DESCRIPTION: start recording impl
   3564  *
   3565  * PARAMETERS : none
   3566  *
   3567  * RETURN     : int32_t type of status
   3568  *              NO_ERROR  -- success
   3569  *              none-zero failure code
   3570  *==========================================================================*/
   3571 int QCamera2HardwareInterface::startRecording()
   3572 {
   3573     int32_t rc = NO_ERROR;
   3574 
   3575     LOGI("E");
   3576     //link meta stream with video channel if low power mode.
   3577     if (isLowPowerMode()) {
   3578         // Find and try to link a metadata stream from preview channel
   3579         QCameraChannel *pMetaChannel = NULL;
   3580         QCameraStream *pMetaStream = NULL;
   3581         QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
   3582 
   3583         if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   3584             pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   3585             uint32_t streamNum = pMetaChannel->getNumOfStreams();
   3586             QCameraStream *pStream = NULL;
   3587             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   3588                 pStream = pMetaChannel->getStreamByIndex(i);
   3589                 if ((NULL != pStream) &&
   3590                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
   3591                     pMetaStream = pStream;
   3592                     break;
   3593                 }
   3594             }
   3595         }
   3596 
   3597         if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   3598             rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
   3599             if (NO_ERROR != rc) {
   3600                 LOGW("Metadata stream link failed %d", rc);
   3601             }
   3602         }
   3603     }
   3604 
   3605     if (rc == NO_ERROR) {
   3606         rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
   3607     }
   3608 
   3609     if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
   3610         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   3611         if (!mParameters.is4k2kVideoResolution()) {
   3612             // Find and try to link a metadata stream from preview channel
   3613             QCameraChannel *pMetaChannel = NULL;
   3614             QCameraStream *pMetaStream = NULL;
   3615 
   3616             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   3617                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   3618                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
   3619                 QCameraStream *pStream = NULL;
   3620                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   3621                     pStream = pMetaChannel->getStreamByIndex(i);
   3622                     if ((NULL != pStream) &&
   3623                             (CAM_STREAM_TYPE_METADATA ==
   3624                             pStream->getMyType())) {
   3625                         pMetaStream = pStream;
   3626                         break;
   3627                     }
   3628                 }
   3629             }
   3630 
   3631             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   3632                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   3633                 if (NO_ERROR != rc) {
   3634                     LOGW("Metadata stream link failed %d", rc);
   3635                 }
   3636             }
   3637         }
   3638         LOGH("START snapshot Channel for TNR processing");
   3639         rc = pChannel->start();
   3640     }
   3641 
   3642     if (rc == NO_ERROR) {
   3643         // Set power Hint for video encoding
   3644         m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
   3645     }
   3646 
   3647     LOGI("X rc = %d", rc);
   3648     return rc;
   3649 }
   3650 
   3651 /*===========================================================================
   3652  * FUNCTION   : stopRecording
   3653  *
   3654  * DESCRIPTION: stop recording impl
   3655  *
   3656  * PARAMETERS : none
   3657  *
   3658  * RETURN     : int32_t type of status
   3659  *              NO_ERROR  -- success
   3660  *              none-zero failure code
   3661  *==========================================================================*/
   3662 int QCamera2HardwareInterface::stopRecording()
   3663 {
   3664     LOGI("E");
   3665     // stop snapshot channel
   3666     if (mParameters.isTNRSnapshotEnabled()) {
   3667         LOGH("STOP snapshot Channel for TNR processing");
   3668         stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   3669     }
   3670     int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
   3671 
   3672     // Disable power hint for video encoding
   3673     m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
   3674 
   3675     LOGI("X rc = %d", rc);
   3676     return rc;
   3677 }
   3678 
   3679 /*===========================================================================
   3680  * FUNCTION   : releaseRecordingFrame
   3681  *
   3682  * DESCRIPTION: return video frame impl
   3683  *
   3684  * PARAMETERS :
   3685  *   @opaque  : ptr to video frame to be returned
   3686  *
   3687  * RETURN     : int32_t type of status
   3688  *              NO_ERROR  -- success
   3689  *              none-zero failure code
   3690  *==========================================================================*/
   3691 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
   3692 {
   3693     int32_t rc = UNKNOWN_ERROR;
   3694     QCameraVideoChannel *pChannel =
   3695         (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
   3696     LOGD("opaque data = %p",opaque);
   3697     if(pChannel != NULL) {
   3698         rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
   3699     }
   3700     return rc;
   3701 }
   3702 
   3703 /*===========================================================================
   3704  * FUNCTION   : autoFocus
   3705  *
   3706  * DESCRIPTION: start auto focus impl
   3707  *
   3708  * PARAMETERS : none
   3709  *
   3710  * RETURN     : int32_t type of status
   3711  *              NO_ERROR  -- success
   3712  *              none-zero failure code
   3713  *==========================================================================*/
   3714 int QCamera2HardwareInterface::autoFocus()
   3715 {
   3716     int rc = NO_ERROR;
   3717     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   3718     LOGH("E");
   3719 
   3720     m_currentFocusState = CAM_AF_STATE_INACTIVE;
   3721 
   3722     switch (focusMode) {
   3723     case CAM_FOCUS_MODE_AUTO:
   3724     case CAM_FOCUS_MODE_MACRO:
   3725     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   3726     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   3727         mActiveAF = true;
   3728         LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
   3729                 focusMode, m_currentFocusState);
   3730         rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
   3731         break;
   3732     case CAM_FOCUS_MODE_INFINITY:
   3733     case CAM_FOCUS_MODE_FIXED:
   3734     case CAM_FOCUS_MODE_EDOF:
   3735     default:
   3736         LOGI("No ops in focusMode (%d)", focusMode);
   3737         rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
   3738         break;
   3739     }
   3740 
   3741     if (NO_ERROR != rc) {
   3742         mActiveAF = false;
   3743     }
   3744     LOGH("X rc = %d", rc);
   3745     return rc;
   3746 }
   3747 
   3748 /*===========================================================================
   3749  * FUNCTION   : cancelAutoFocus
   3750  *
   3751  * DESCRIPTION: cancel auto focus impl
   3752  *
   3753  * PARAMETERS : none
   3754  *
   3755  * RETURN     : int32_t type of status
   3756  *              NO_ERROR  -- success
   3757  *              none-zero failure code
   3758  *==========================================================================*/
   3759 int QCamera2HardwareInterface::cancelAutoFocus()
   3760 {
   3761     int rc = NO_ERROR;
   3762     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   3763 
   3764     switch (focusMode) {
   3765     case CAM_FOCUS_MODE_AUTO:
   3766     case CAM_FOCUS_MODE_MACRO:
   3767     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   3768     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   3769         mActiveAF = false;
   3770         rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
   3771         break;
   3772     case CAM_FOCUS_MODE_INFINITY:
   3773     case CAM_FOCUS_MODE_FIXED:
   3774     case CAM_FOCUS_MODE_EDOF:
   3775     default:
   3776         LOGD("No ops in focusMode (%d)", focusMode);
   3777         break;
   3778     }
   3779     return rc;
   3780 }
   3781 
   3782 /*===========================================================================
   3783  * FUNCTION   : processUFDumps
   3784  *
   3785  * DESCRIPTION: process UF jpeg dumps for refocus support
   3786  *
   3787  * PARAMETERS :
   3788  *   @evt     : payload of jpeg event, including information about jpeg encoding
   3789  *              status, jpeg size and so on.
   3790  *
   3791  * RETURN     : int32_t type of status
   3792  *              NO_ERROR  -- success
   3793  *              none-zero failure code
   3794  *
   3795  * NOTE       : none
   3796  *==========================================================================*/
   3797 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
   3798 {
   3799    bool ret = true;
   3800    if (mParameters.isUbiRefocus()) {
   3801        int index = (int)getOutputImageCount();
   3802        bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
   3803        char name[FILENAME_MAX];
   3804 
   3805        camera_memory_t *jpeg_mem = NULL;
   3806        omx_jpeg_ouput_buf_t *jpeg_out = NULL;
   3807        size_t dataLen;
   3808        uint8_t *dataPtr;
   3809        if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   3810            LOGE("Init PProc Deferred work failed");
   3811            return false;
   3812        }
   3813        if (!m_postprocessor.getJpegMemOpt()) {
   3814            dataLen = evt->out_data.buf_filled_len;
   3815            dataPtr = evt->out_data.buf_vaddr;
   3816        } else {
   3817            jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
   3818            if (!jpeg_out) {
   3819               LOGE("Null pointer detected");
   3820               return false;
   3821            }
   3822            jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
   3823            if (!jpeg_mem) {
   3824               LOGE("Null pointer detected");
   3825               return false;
   3826            }
   3827            dataPtr = (uint8_t *)jpeg_mem->data;
   3828            dataLen = jpeg_mem->size;
   3829        }
   3830 
   3831        if (allFocusImage)  {
   3832            snprintf(name, sizeof(name), "AllFocusImage");
   3833            index = -1;
   3834        } else {
   3835            snprintf(name, sizeof(name), "%d", 0);
   3836        }
   3837        CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
   3838            dataPtr, dataLen);
   3839        LOGD("Dump the image %d %d allFocusImage %d",
   3840            getOutputImageCount(), index, allFocusImage);
   3841        setOutputImageCount(getOutputImageCount() + 1);
   3842        if (!allFocusImage) {
   3843            ret = false;
   3844        }
   3845    }
   3846    return ret;
   3847 }
   3848 
   3849 /*===========================================================================
   3850  * FUNCTION   : unconfigureAdvancedCapture
   3851  *
   3852  * DESCRIPTION: unconfigure Advanced Capture.
   3853  *
   3854  * PARAMETERS : none
   3855  *
   3856  * RETURN     : int32_t type of status
   3857  *              NO_ERROR  -- success
   3858  *              none-zero failure code
   3859  *==========================================================================*/
   3860 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
   3861 {
   3862     int32_t rc = NO_ERROR;
   3863 
   3864     if (mAdvancedCaptureConfigured) {
   3865 
   3866         mAdvancedCaptureConfigured = false;
   3867 
   3868         if(mIs3ALocked) {
   3869             mParameters.set3ALock(false);
   3870             mIs3ALocked = false;
   3871         }
   3872         if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
   3873             rc = mParameters.setToneMapMode(true, true);
   3874             if (rc != NO_ERROR) {
   3875                 LOGW("Failed to enable tone map during HDR/AEBracketing");
   3876             }
   3877             mHDRBracketingEnabled = false;
   3878             rc = mParameters.stopAEBracket();
   3879         } else if ((mParameters.isChromaFlashEnabled())
   3880                 || (mFlashNeeded && !mLongshotEnabled)
   3881                 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
   3882                 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   3883             rc = mParameters.resetFrameCapture(TRUE);
   3884         } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   3885             rc = configureAFBracketing(false);
   3886         } else if (mParameters.isOptiZoomEnabled()) {
   3887             rc = mParameters.setAndCommitZoom(mZoomLevel);
   3888             setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
   3889         } else if (mParameters.isStillMoreEnabled()) {
   3890             cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
   3891             stillmore_config.burst_count = 0;
   3892             mParameters.setStillMoreSettings(stillmore_config);
   3893 
   3894             /* If SeeMore is running, it will handle re-enabling tone map */
   3895             if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
   3896                 rc = mParameters.setToneMapMode(true, true);
   3897                 if (rc != NO_ERROR) {
   3898                     LOGW("Failed to enable tone map during StillMore");
   3899                 }
   3900             }
   3901 
   3902             /* Re-enable Tintless */
   3903             mParameters.setTintless(true);
   3904         } else {
   3905             LOGW("No Advanced Capture feature enabled!!");
   3906             rc = BAD_VALUE;
   3907         }
   3908     }
   3909 
   3910     return rc;
   3911 }
   3912 
   3913 /*===========================================================================
   3914  * FUNCTION   : configureAdvancedCapture
   3915  *
   3916  * DESCRIPTION: configure Advanced Capture.
   3917  *
   3918  * PARAMETERS : none
   3919  *
   3920  * RETURN     : int32_t type of status
   3921  *              NO_ERROR  -- success
   3922  *              none-zero failure code
   3923  *==========================================================================*/
   3924 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
   3925 {
   3926     LOGH("E");
   3927     int32_t rc = NO_ERROR;
   3928 
   3929     rc = mParameters.checkFeatureConcurrency();
   3930     if (rc != NO_ERROR) {
   3931         LOGE("Cannot support Advanced capture modes");
   3932         return rc;
   3933     }
   3934 
   3935     setOutputImageCount(0);
   3936     mInputCount = 0;
   3937     mAdvancedCaptureConfigured = true;
   3938     /* Display should be disabled for advanced modes */
   3939     bool bSkipDisplay = true;
   3940 
   3941     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
   3942         // no Advance capture settings for Aux camera
   3943         LOGH("X Secondary Camera, no need to process!! ");
   3944         return rc;
   3945     }
   3946 
   3947     /* Do not stop display if in stillmore livesnapshot */
   3948     if (mParameters.isStillMoreEnabled() &&
   3949             mParameters.isSeeMoreEnabled()) {
   3950         bSkipDisplay = false;
   3951     }
   3952     if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   3953         rc = configureAFBracketing();
   3954     } else if (mParameters.isOptiZoomEnabled()) {
   3955         rc = configureOptiZoom();
   3956     } else if(mParameters.isHDREnabled()) {
   3957         rc = configureHDRBracketing();
   3958         if (mHDRBracketingEnabled) {
   3959             rc = mParameters.setToneMapMode(false, true);
   3960             if (rc != NO_ERROR) {
   3961                 LOGW("Failed to disable tone map during HDR");
   3962             }
   3963         }
   3964     } else if (mParameters.isAEBracketEnabled()) {
   3965         rc = mParameters.setToneMapMode(false, true);
   3966         if (rc != NO_ERROR) {
   3967             LOGW("Failed to disable tone map during AEBracketing");
   3968         }
   3969         rc = configureAEBracketing();
   3970     } else if (mParameters.isStillMoreEnabled()) {
   3971         rc = configureStillMore();
   3972     } else if ((mParameters.isChromaFlashEnabled())
   3973             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
   3974             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   3975         rc = mParameters.configFrameCapture(TRUE);
   3976     } else if (mFlashNeeded && !mLongshotEnabled) {
   3977         rc = mParameters.configFrameCapture(TRUE);
   3978         bSkipDisplay = false;
   3979     } else {
   3980         LOGH("Advanced Capture feature not enabled!! ");
   3981         mAdvancedCaptureConfigured = false;
   3982         bSkipDisplay = false;
   3983     }
   3984 
   3985     LOGH("Stop preview temporarily for advanced captures");
   3986     setDisplaySkip(bSkipDisplay);
   3987 
   3988     LOGH("X rc = %d", rc);
   3989     return rc;
   3990 }
   3991 
   3992 /*===========================================================================
   3993  * FUNCTION   : configureAFBracketing
   3994  *
   3995  * DESCRIPTION: configure AF Bracketing.
   3996  *
   3997  * PARAMETERS : none
   3998  *
   3999  * RETURN     : int32_t type of status
   4000  *              NO_ERROR  -- success
   4001  *              none-zero failure code
   4002  *==========================================================================*/
   4003 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
   4004 {
   4005     LOGH("E");
   4006     int32_t rc = NO_ERROR;
   4007     cam_af_bracketing_t *af_bracketing_need;
   4008 
   4009     if (mParameters.isUbiRefocus()) {
   4010         af_bracketing_need =
   4011                 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
   4012     } else {
   4013         af_bracketing_need =
   4014                 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
   4015     }
   4016 
   4017     //Enable AF Bracketing.
   4018     cam_af_bracketing_t afBracket;
   4019     memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
   4020     afBracket.enable = enable;
   4021     afBracket.burst_count = af_bracketing_need->burst_count;
   4022 
   4023     for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
   4024         afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
   4025         LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
   4026     }
   4027     //Send cmd to backend to set AF Bracketing for Ubi Focus.
   4028     rc = mParameters.commitAFBracket(afBracket);
   4029     if ( NO_ERROR != rc ) {
   4030         LOGE("cannot configure AF bracketing");
   4031         return rc;
   4032     }
   4033     if (enable) {
   4034         mParameters.set3ALock(true);
   4035         mIs3ALocked = true;
   4036     }
   4037     LOGH("X rc = %d", rc);
   4038     return rc;
   4039 }
   4040 
   4041 /*===========================================================================
   4042  * FUNCTION   : configureHDRBracketing
   4043  *
   4044  * DESCRIPTION: configure HDR Bracketing.
   4045  *
   4046  * PARAMETERS : none
   4047  *
   4048  * RETURN     : int32_t type of status
   4049  *              NO_ERROR  -- success
   4050  *              none-zero failure code
   4051  *==========================================================================*/
   4052 int32_t QCamera2HardwareInterface::configureHDRBracketing()
   4053 {
   4054     LOGH("E");
   4055     int32_t rc = NO_ERROR;
   4056 
   4057     cam_hdr_bracketing_info_t& hdrBracketingSetting =
   4058             gCamCapability[mCameraId]->hdr_bracketing_setting;
   4059 
   4060     // 'values' should be in "idx1,idx2,idx3,..." format
   4061     uint32_t hdrFrameCount =
   4062             hdrBracketingSetting.num_frames;
   4063     LOGH("HDR values %d, %d frame count: %u",
   4064           (int8_t) hdrBracketingSetting.exp_val.values[0],
   4065           (int8_t) hdrBracketingSetting.exp_val.values[1],
   4066           hdrFrameCount);
   4067 
   4068     // Enable AE Bracketing for HDR
   4069     cam_exp_bracketing_t aeBracket;
   4070     memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
   4071     aeBracket.mode =
   4072         hdrBracketingSetting.exp_val.mode;
   4073 
   4074     if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
   4075         mHDRBracketingEnabled = true;
   4076     }
   4077 
   4078     String8 tmp;
   4079     for (uint32_t i = 0; i < hdrFrameCount; i++) {
   4080         tmp.appendFormat("%d",
   4081             (int8_t) hdrBracketingSetting.exp_val.values[i]);
   4082         tmp.append(",");
   4083     }
   4084     if (mParameters.isHDR1xFrameEnabled()
   4085         && mParameters.isHDR1xExtraBufferNeeded()) {
   4086             tmp.appendFormat("%d", 0);
   4087             tmp.append(",");
   4088     }
   4089 
   4090     if( !tmp.isEmpty() &&
   4091         ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
   4092         //Trim last comma
   4093         memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
   4094         memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
   4095     }
   4096 
   4097     LOGH("HDR config values %s",
   4098           aeBracket.values);
   4099     rc = mParameters.setHDRAEBracket(aeBracket);
   4100     if ( NO_ERROR != rc ) {
   4101         LOGE("cannot configure HDR bracketing");
   4102         return rc;
   4103     }
   4104     LOGH("X rc = %d", rc);
   4105     return rc;
   4106 }
   4107 
   4108 /*===========================================================================
   4109  * FUNCTION   : configureAEBracketing
   4110  *
   4111  * DESCRIPTION: configure AE Bracketing.
   4112  *
   4113  * PARAMETERS : none
   4114  *
   4115  * RETURN     : int32_t type of status
   4116  *              NO_ERROR  -- success
   4117  *              none-zero failure code
   4118  *==========================================================================*/
   4119 int32_t QCamera2HardwareInterface::configureAEBracketing()
   4120 {
   4121     LOGH("E");
   4122     int32_t rc = NO_ERROR;
   4123 
   4124     rc = mParameters.setAEBracketing();
   4125     if ( NO_ERROR != rc ) {
   4126         LOGE("cannot configure AE bracketing");
   4127         return rc;
   4128     }
   4129     LOGH("X rc = %d", rc);
   4130     return rc;
   4131 }
   4132 
   4133 /*===========================================================================
   4134  * FUNCTION   : configureOptiZoom
   4135  *
   4136  * DESCRIPTION: configure Opti Zoom.
   4137  *
   4138  * PARAMETERS : none
   4139  *
   4140  * RETURN     : int32_t type of status
   4141  *              NO_ERROR  -- success
   4142  *              none-zero failure code
   4143  *==========================================================================*/
   4144 int32_t QCamera2HardwareInterface::configureOptiZoom()
   4145 {
   4146     int32_t rc = NO_ERROR;
   4147 
   4148     //store current zoom level.
   4149     mZoomLevel = mParameters.getParmZoomLevel();
   4150 
   4151     //set zoom level to 1x;
   4152     mParameters.setAndCommitZoom(0);
   4153 
   4154     mParameters.set3ALock(true);
   4155     mIs3ALocked = true;
   4156 
   4157     return rc;
   4158 }
   4159 
   4160 /*===========================================================================
   4161  * FUNCTION   : configureStillMore
   4162  *
   4163  * DESCRIPTION: configure StillMore.
   4164  *
   4165  * PARAMETERS : none
   4166  *
   4167  * RETURN     : int32_t type of status
   4168  *              NO_ERROR  -- success
   4169  *              none-zero failure code
   4170  *==========================================================================*/
   4171 int32_t QCamera2HardwareInterface::configureStillMore()
   4172 {
   4173     int32_t rc = NO_ERROR;
   4174     uint8_t burst_cnt = 0;
   4175     cam_still_more_t stillmore_config;
   4176     cam_still_more_t stillmore_cap;
   4177 
   4178     /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
   4179     if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
   4180         rc = mParameters.setToneMapMode(false, true);
   4181         if (rc != NO_ERROR) {
   4182             LOGW("Failed to disable tone map during StillMore");
   4183         }
   4184     }
   4185 
   4186     /* Lock 3A */
   4187     mParameters.set3ALock(true);
   4188     mIs3ALocked = true;
   4189 
   4190     /* Disable Tintless */
   4191     mParameters.setTintless(false);
   4192 
   4193     /* Initialize burst count from capability */
   4194     stillmore_cap = mParameters.getStillMoreCapability();
   4195     burst_cnt = stillmore_cap.max_burst_count;
   4196 
   4197     /* Reconfigure burst count from dynamic scene data */
   4198     cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
   4199     if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
   4200             dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
   4201         burst_cnt = dynamic_img_data.input_count;
   4202     }
   4203 
   4204     /* Reconfigure burst count in the case of liveshot */
   4205     if (mParameters.isSeeMoreEnabled()) {
   4206         burst_cnt = 1;
   4207     }
   4208 
   4209     /* Reconfigure burst count from user input */
   4210     char prop[PROPERTY_VALUE_MAX];
   4211     property_get("persist.camera.imglib.stillmore", prop, "0");
   4212     uint8_t burst_setprop = (uint32_t)atoi(prop);
   4213     if (burst_setprop != 0)  {
   4214        if ((burst_setprop < stillmore_cap.min_burst_count) ||
   4215                (burst_setprop > stillmore_cap.max_burst_count)) {
   4216            burst_cnt = stillmore_cap.max_burst_count;
   4217        } else {
   4218            burst_cnt = burst_setprop;
   4219        }
   4220     }
   4221 
   4222     memset(&stillmore_config, 0, sizeof(cam_still_more_t));
   4223     stillmore_config.burst_count = burst_cnt;
   4224     mParameters.setStillMoreSettings(stillmore_config);
   4225 
   4226     LOGH("Stillmore burst %d", burst_cnt);
   4227 
   4228     return rc;
   4229 }
   4230 
   4231 /*===========================================================================
   4232  * FUNCTION   : stopAdvancedCapture
   4233  *
   4234  * DESCRIPTION: stops advanced capture based on capture type
   4235  *
   4236  * PARAMETERS :
   4237  *   @pChannel : channel.
   4238  *
   4239  * RETURN     : int32_t type of status
   4240  *              NO_ERROR  -- success
   4241  *              none-zero failure code
   4242  *==========================================================================*/
   4243 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
   4244         QCameraPicChannel *pChannel)
   4245 {
   4246     LOGH("stop bracketig");
   4247     int32_t rc = NO_ERROR;
   4248 
   4249     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4250         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
   4251     } else if (mParameters.isChromaFlashEnabled()
   4252             || (mFlashNeeded && !mLongshotEnabled)
   4253             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
   4254             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4255         rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
   4256     } else if(mParameters.isHDREnabled()
   4257             || mParameters.isAEBracketEnabled()) {
   4258         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
   4259     } else if (mParameters.isOptiZoomEnabled()) {
   4260         rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
   4261     } else if (mParameters.isStillMoreEnabled()) {
   4262         LOGH("stopAdvancedCapture not needed for StillMore");
   4263     } else {
   4264         LOGH("No Advanced Capture feature enabled!");
   4265         rc = BAD_VALUE;
   4266     }
   4267     return rc;
   4268 }
   4269 
   4270 /*===========================================================================
   4271  * FUNCTION   : startAdvancedCapture
   4272  *
   4273  * DESCRIPTION: starts advanced capture based on capture type
   4274  *
   4275  * PARAMETERS :
   4276  *   @pChannel : channel.
   4277  *
   4278  * RETURN     : int32_t type of status
   4279  *              NO_ERROR  -- success
   4280  *              none-zero failure code
   4281  *==========================================================================*/
   4282 int32_t QCamera2HardwareInterface::startAdvancedCapture(
   4283         QCameraPicChannel *pChannel)
   4284 {
   4285     LOGH("Start bracketing");
   4286     int32_t rc = NO_ERROR;
   4287 
   4288     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4289         rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
   4290     } else if (mParameters.isOptiZoomEnabled()) {
   4291         rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
   4292     } else if (mParameters.isStillMoreEnabled()) {
   4293         LOGH("startAdvancedCapture not needed for StillMore");
   4294     } else if (mParameters.isHDREnabled()
   4295             || mParameters.isAEBracketEnabled()) {
   4296         rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
   4297     } else if (mParameters.isChromaFlashEnabled()
   4298             || (mFlashNeeded && !mLongshotEnabled)
   4299             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
   4300             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4301         cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
   4302         rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
   4303     } else {
   4304         LOGE("No Advanced Capture feature enabled!");
   4305         rc = BAD_VALUE;
   4306     }
   4307     return rc;
   4308 }
   4309 
   4310 /*===========================================================================
   4311  * FUNCTION   : preTakePicture
   4312  *
   4313  * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
   4314  *
   4315  * PARAMETERS : none
   4316  *
   4317  * RETURN     : int32_t type of status
   4318  *              NO_ERROR  -- success
   4319  *              none-zero failure code
   4320  *==========================================================================*/
   4321 int QCamera2HardwareInterface::preTakePicture()
   4322 {
   4323     int32_t rc = NO_ERROR;
   4324     LOGH("E");
   4325     if (mParameters.getRecordingHintValue() == true) {
   4326 
   4327         // Give HWI control to restart preview only in single camera mode.
   4328         // In dual-cam mode, this control belongs to muxer.
   4329         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   4330             LOGH("restart preview if rec hint is true and preview is running");
   4331             stopPreview();
   4332             mParameters.updateRecordingHintValue(FALSE);
   4333             // start preview again
   4334             rc = preparePreview();
   4335             if (rc == NO_ERROR) {
   4336                 rc = startPreview();
   4337                 if (rc != NO_ERROR) {
   4338                     unpreparePreview();
   4339                 }
   4340             }
   4341         }
   4342         else
   4343         {
   4344             // For dual cam mode, update the flag mPreviewRestartNeeded to true
   4345             // Restart control will be handled by muxer.
   4346             mPreviewRestartNeeded = true;
   4347         }
   4348     }
   4349 
   4350     LOGH("X rc = %d", rc);
   4351     return rc;
   4352 }
   4353 
   4354 /*===========================================================================
   4355  * FUNCTION   : takePicture
   4356  *
   4357  * DESCRIPTION: take picture impl
   4358  *
   4359  * PARAMETERS : none
   4360  *
   4361  * RETURN     : int32_t type of status
   4362  *              NO_ERROR  -- success
   4363  *              none-zero failure code
   4364  *==========================================================================*/
   4365 int QCamera2HardwareInterface::takePicture()
   4366 {
   4367     int rc = NO_ERROR;
   4368 
   4369     // Get total number for snapshots (retro + regular)
   4370     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
   4371     // Get number of retro-active snapshots
   4372     uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
   4373     LOGH("E");
   4374 
   4375     //Set rotation value from user settings as Jpeg rotation
   4376     //to configure back-end modules.
   4377     mParameters.setJpegRotation(mParameters.getRotation());
   4378 
   4379     // Check if retro-active snapshots are not enabled
   4380     if (!isRetroPicture() || !mParameters.isZSLMode()) {
   4381       numRetroSnapshots = 0;
   4382       LOGH("Reset retro snaphot count to zero");
   4383     }
   4384 
   4385     //Do special configure for advanced capture modes.
   4386     rc = configureAdvancedCapture();
   4387     if (rc != NO_ERROR) {
   4388         LOGE("Unsupported capture call");
   4389         return rc;
   4390     }
   4391 
   4392     if (mAdvancedCaptureConfigured) {
   4393         numSnapshots = mParameters.getBurstCountForAdvancedCapture();
   4394     }
   4395     LOGI("snap count = %d zsl = %d advanced = %d",
   4396             numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured);
   4397 
   4398     if (mParameters.isZSLMode()) {
   4399         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   4400         QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
   4401         if (NULL != pPicChannel) {
   4402 
   4403             if (mParameters.getofflineRAW()) {
   4404                 startRAWChannel(pPicChannel);
   4405                 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
   4406                 if (pPicChannel == NULL) {
   4407                     LOGE("RAW Channel is NULL in Manual capture mode");
   4408                     stopRAWChannel();
   4409                     return UNKNOWN_ERROR;
   4410                 }
   4411             }
   4412 
   4413             rc = configureOnlineRotation(*pPicChannel);
   4414             if (rc != NO_ERROR) {
   4415                 LOGE("online rotation failed");
   4416                 return rc;
   4417             }
   4418 
   4419             // start postprocessor
   4420             DeferWorkArgs args;
   4421             memset(&args, 0, sizeof(DeferWorkArgs));
   4422 
   4423             args.pprocArgs = pPicChannel;
   4424 
   4425             // No need to wait for mInitPProcJob here, because it was
   4426             // queued in startPreview, and will definitely be processed before
   4427             // mReprocJob can begin.
   4428             mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   4429                     args);
   4430             if (mReprocJob == 0) {
   4431                 LOGE("Failure: Unable to start pproc");
   4432                 return -ENOMEM;
   4433             }
   4434 
   4435             // Check if all preview buffers are mapped before creating
   4436             // a jpeg session as preview stream buffers are queried during the same
   4437             uint8_t numStreams = pChannel->getNumOfStreams();
   4438             QCameraStream *pStream = NULL;
   4439             QCameraStream *pPreviewStream = NULL;
   4440             for (uint8_t i = 0 ; i < numStreams ; i++ ) {
   4441                 pStream = pChannel->getStreamByIndex(i);
   4442                 if (!pStream)
   4443                     continue;
   4444                 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
   4445                     pPreviewStream = pStream;
   4446                     break;
   4447                 }
   4448             }
   4449             if (pPreviewStream != NULL) {
   4450                 Mutex::Autolock l(mMapLock);
   4451                 QCameraMemory *pMemory = pStream->getStreamBufs();
   4452                 if (!pMemory) {
   4453                     LOGE("Error!! pMemory is NULL");
   4454                     return -ENOMEM;
   4455                 }
   4456 
   4457                 uint8_t waitCnt = 2;
   4458                 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
   4459                     LOGL(" Waiting for preview buffers to be mapped");
   4460                     mMapCond.waitRelative(
   4461                             mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
   4462                     LOGL("Wait completed!!");
   4463                     waitCnt--;
   4464                 }
   4465                 // If all buffers are not mapped after retries, assert
   4466                 assert(pMemory->checkIfAllBuffersMapped());
   4467             } else {
   4468                 assert(pPreviewStream);
   4469             }
   4470 
   4471             // Create JPEG session
   4472             mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   4473                     args);
   4474             if (mJpegJob == 0) {
   4475                 LOGE("Failed to queue CREATE_JPEG_SESSION");
   4476                 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4477                         LOGE("Reprocess Deferred work was failed");
   4478                 }
   4479                 m_postprocessor.stop();
   4480                 return -ENOMEM;
   4481             }
   4482 
   4483             if (mAdvancedCaptureConfigured) {
   4484                 rc = startAdvancedCapture(pPicChannel);
   4485                 if (rc != NO_ERROR) {
   4486                     LOGE("cannot start zsl advanced capture");
   4487                     return rc;
   4488                 }
   4489             }
   4490             if (mLongshotEnabled && mPrepSnapRun) {
   4491                 mCameraHandle->ops->start_zsl_snapshot(
   4492                         mCameraHandle->camera_handle,
   4493                         pPicChannel->getMyHandle());
   4494             }
   4495             // If frame sync is ON and it is a SECONDARY camera,
   4496             // we do not need to send the take picture command to interface
   4497             // It will be handled along with PRIMARY camera takePicture request
   4498             mm_camera_req_buf_t buf;
   4499             memset(&buf, 0x0, sizeof(buf));
   4500             if ((!mParameters.isAdvCamFeaturesEnabled() &&
   4501                     !mFlashNeeded &&
   4502                     !isLongshotEnabled() &&
   4503                     getRelatedCamSyncInfo()->is_frame_sync_enabled) &&
   4504                     (getRelatedCamSyncInfo()->sync_control ==
   4505                     CAM_SYNC_RELATED_SENSORS_ON)) {
   4506                 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
   4507                     buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
   4508                     buf.num_buf_requested = numSnapshots;
   4509                     rc = pPicChannel->takePicture(&buf);
   4510                     if (rc != NO_ERROR) {
   4511                         LOGE("FS_DBG cannot take ZSL picture, stop pproc");
   4512                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4513                             LOGE("Reprocess Deferred work failed");
   4514                             return UNKNOWN_ERROR;
   4515                         }
   4516                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   4517                             LOGE("Jpeg Deferred work failed");
   4518                             return UNKNOWN_ERROR;
   4519                         }
   4520                         m_postprocessor.stop();
   4521                         return rc;
   4522                     }
   4523                     LOGI("PRIMARY camera: send frame sync takePicture!!");
   4524                 }
   4525             } else {
   4526                 buf.type = MM_CAMERA_REQ_SUPER_BUF;
   4527                 buf.num_buf_requested = numSnapshots;
   4528                 buf.num_retro_buf_requested = numRetroSnapshots;
   4529                 rc = pPicChannel->takePicture(&buf);
   4530                 if (rc != NO_ERROR) {
   4531                     LOGE("cannot take ZSL picture, stop pproc");
   4532                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4533                             LOGE("Reprocess Deferred work failed");
   4534                             return UNKNOWN_ERROR;
   4535                         }
   4536                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   4537                             LOGE("Jpeg Deferred work failed");
   4538                             return UNKNOWN_ERROR;
   4539                         }
   4540                     m_postprocessor.stop();
   4541                     return rc;
   4542                 }
   4543             }
   4544         } else {
   4545             LOGE("ZSL channel is NULL");
   4546             return UNKNOWN_ERROR;
   4547         }
   4548     } else {
   4549 
   4550         // start snapshot
   4551         if (mParameters.isJpegPictureFormat() ||
   4552                 mParameters.isNV16PictureFormat() ||
   4553                 mParameters.isNV21PictureFormat()) {
   4554 
   4555             //STOP Preview for Non ZSL use case
   4556             stopPreview();
   4557 
   4558             //Config CAPTURE channels
   4559             rc = declareSnapshotStreams();
   4560             if (NO_ERROR != rc) {
   4561                 return rc;
   4562             }
   4563 
   4564             rc = addCaptureChannel();
   4565             if ((rc == NO_ERROR) &&
   4566                     (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
   4567 
   4568                 if (!mParameters.getofflineRAW()) {
   4569                     rc = configureOnlineRotation(
   4570                         *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
   4571                     if (rc != NO_ERROR) {
   4572                         LOGE("online rotation failed");
   4573                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
   4574                         return rc;
   4575                     }
   4576                 }
   4577 
   4578                 DeferWorkArgs args;
   4579                 memset(&args, 0, sizeof(DeferWorkArgs));
   4580 
   4581                 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
   4582 
   4583                 // No need to wait for mInitPProcJob here, because it was
   4584                 // queued in startPreview, and will definitely be processed before
   4585                 // mReprocJob can begin.
   4586                 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   4587                         args);
   4588                 if (mReprocJob == 0) {
   4589                     LOGE("Failure: Unable to start pproc");
   4590                     return -ENOMEM;
   4591                 }
   4592 
   4593                 // Create JPEG session
   4594                 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   4595                         args);
   4596                 if (mJpegJob == 0) {
   4597                     LOGE("Failed to queue CREATE_JPEG_SESSION");
   4598                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4599                         LOGE("Reprocess Deferred work was failed");
   4600                     }
   4601                     m_postprocessor.stop();
   4602                     return -ENOMEM;
   4603                 }
   4604 
   4605                 // start catpure channel
   4606                 rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
   4607                 if (rc != NO_ERROR) {
   4608                     LOGE("cannot start capture channel");
   4609                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4610                         LOGE("Reprocess Deferred work failed");
   4611                         return UNKNOWN_ERROR;
   4612                     }
   4613                     if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   4614                         LOGE("Jpeg Deferred work failed");
   4615                         return UNKNOWN_ERROR;
   4616                     }
   4617                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
   4618                     return rc;
   4619                 }
   4620 
   4621                 QCameraPicChannel *pCapChannel =
   4622                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
   4623                 if (NULL != pCapChannel) {
   4624                     if (mParameters.isUbiFocusEnabled() ||
   4625                             mParameters.isUbiRefocus() ||
   4626                             mParameters.isChromaFlashEnabled()) {
   4627                         rc = startAdvancedCapture(pCapChannel);
   4628                         if (rc != NO_ERROR) {
   4629                             LOGE("cannot start advanced capture");
   4630                             return rc;
   4631                         }
   4632                     }
   4633                 }
   4634                 if ( mLongshotEnabled ) {
   4635                     rc = longShot();
   4636                     if (NO_ERROR != rc) {
   4637                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4638                             LOGE("Reprocess Deferred work failed");
   4639                             return UNKNOWN_ERROR;
   4640                         }
   4641                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   4642                             LOGE("Jpeg Deferred work failed");
   4643                             return UNKNOWN_ERROR;
   4644                         }
   4645                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
   4646                         return rc;
   4647                     }
   4648                 }
   4649             } else {
   4650                 LOGE("cannot add capture channel");
   4651                 delChannel(QCAMERA_CH_TYPE_CAPTURE);
   4652                 return rc;
   4653             }
   4654         } else {
   4655             // Stop Preview before taking NZSL snapshot
   4656             stopPreview();
   4657 
   4658             rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
   4659             if (NO_ERROR != rc) {
   4660                 LOGE("Raw dimension update failed %d", rc);
   4661                 return rc;
   4662             }
   4663 
   4664             rc = declareSnapshotStreams();
   4665             if (NO_ERROR != rc) {
   4666                 LOGE("RAW stream info configuration failed %d", rc);
   4667                 return rc;
   4668             }
   4669 
   4670             rc = addChannel(QCAMERA_CH_TYPE_RAW);
   4671             if (rc == NO_ERROR) {
   4672                 // start postprocessor
   4673                 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   4674                     LOGE("Reprocess Deferred work failed");
   4675                     return UNKNOWN_ERROR;
   4676                 }
   4677 
   4678                 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
   4679                 if (rc != NO_ERROR) {
   4680                     LOGE("cannot start postprocessor");
   4681                     delChannel(QCAMERA_CH_TYPE_RAW);
   4682                     return rc;
   4683                 }
   4684 
   4685                 rc = startChannel(QCAMERA_CH_TYPE_RAW);
   4686                 if (rc != NO_ERROR) {
   4687                     LOGE("cannot start raw channel");
   4688                     m_postprocessor.stop();
   4689                     delChannel(QCAMERA_CH_TYPE_RAW);
   4690                     return rc;
   4691                 }
   4692             } else {
   4693                 LOGE("cannot add raw channel");
   4694                 return rc;
   4695             }
   4696         }
   4697     }
   4698 
   4699     //When take picture, stop sending preview callbacks to APP
   4700     m_stateMachine.setPreviewCallbackNeeded(false);
   4701     LOGI("X rc = %d", rc);
   4702     return rc;
   4703 }
   4704 
   4705 /*===========================================================================
   4706  * FUNCTION   : configureOnlineRotation
   4707  *
   4708  * DESCRIPTION: Configure backend with expected rotation for snapshot stream
   4709  *
   4710  * PARAMETERS :
   4711  *    @ch     : Channel containing a snapshot stream
   4712  *
   4713  * RETURN     : int32_t type of status
   4714  *              NO_ERROR  -- success
   4715  *              none-zero failure code
   4716  *==========================================================================*/
   4717 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
   4718 {
   4719     int rc = NO_ERROR;
   4720     uint32_t streamId = 0;
   4721     QCameraStream *pStream = NULL;
   4722 
   4723     for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
   4724         QCameraStream *stream = ch.getStreamByIndex(i);
   4725         if ((NULL != stream) &&
   4726                 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
   4727                 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
   4728             pStream = stream;
   4729             break;
   4730         }
   4731     }
   4732 
   4733     if (NULL == pStream) {
   4734         LOGE("No snapshot stream found!");
   4735         return BAD_VALUE;
   4736     }
   4737 
   4738     streamId = pStream->getMyServerID();
   4739     // Update online rotation configuration
   4740     rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
   4741             mParameters.getDeviceRotation());
   4742     if (rc != NO_ERROR) {
   4743         LOGE("addOnlineRotation failed %d", rc);
   4744         return rc;
   4745     }
   4746 
   4747     return rc;
   4748 }
   4749 
   4750 /*===========================================================================
   4751  * FUNCTION   : declareSnapshotStreams
   4752  *
   4753  * DESCRIPTION: Configure backend with expected snapshot streams
   4754  *
   4755  * PARAMETERS : none
   4756  *
   4757  * RETURN     : int32_t type of status
   4758  *              NO_ERROR  -- success
   4759  *              none-zero failure code
   4760  *==========================================================================*/
   4761 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
   4762 {
   4763     int rc = NO_ERROR;
   4764 
   4765     // Update stream info configuration
   4766     rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
   4767     if (rc != NO_ERROR) {
   4768         LOGE("setStreamConfigure failed %d", rc);
   4769         return rc;
   4770     }
   4771 
   4772     return rc;
   4773 }
   4774 
   4775 /*===========================================================================
   4776  * FUNCTION   : longShot
   4777  *
   4778  * DESCRIPTION: Queue one more ZSL frame
   4779  *              in the longshot pipe.
   4780  *
   4781  * PARAMETERS : none
   4782  *
   4783  * RETURN     : int32_t type of status
   4784  *              NO_ERROR  -- success
   4785  *              none-zero failure code
   4786  *==========================================================================*/
   4787 int32_t QCamera2HardwareInterface::longShot()
   4788 {
   4789     int32_t rc = NO_ERROR;
   4790     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
   4791     QCameraPicChannel *pChannel = NULL;
   4792 
   4793     if (mParameters.isZSLMode()) {
   4794         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   4795     } else {
   4796         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
   4797     }
   4798 
   4799     if (NULL != pChannel) {
   4800         mm_camera_req_buf_t buf;
   4801         memset(&buf, 0x0, sizeof(buf));
   4802         buf.type = MM_CAMERA_REQ_SUPER_BUF;
   4803         buf.num_buf_requested = numSnapshots;
   4804         rc = pChannel->takePicture(&buf);
   4805     } else {
   4806         LOGE("Capture channel not initialized!");
   4807         rc = NO_INIT;
   4808         goto end;
   4809     }
   4810 
   4811 end:
   4812     return rc;
   4813 }
   4814 
   4815 /*===========================================================================
   4816  * FUNCTION   : stopCaptureChannel
   4817  *
   4818  * DESCRIPTION: Stops capture channel
   4819  *
   4820  * PARAMETERS :
   4821  *   @destroy : Set to true to stop and delete camera channel.
   4822  *              Set to false to only stop capture channel.
   4823  *
   4824  * RETURN     : int32_t type of status
   4825  *              NO_ERROR  -- success
   4826  *              none-zero failure code
   4827  *==========================================================================*/
   4828 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
   4829 {
   4830     int rc = NO_ERROR;
   4831     if (mParameters.isJpegPictureFormat() ||
   4832         mParameters.isNV16PictureFormat() ||
   4833         mParameters.isNV21PictureFormat()) {
   4834         rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
   4835         if (destroy && (NO_ERROR == rc)) {
   4836             // Destroy camera channel but dont release context
   4837             waitDeferredWork(mJpegJob);
   4838             rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
   4839         }
   4840     }
   4841 
   4842     return rc;
   4843 }
   4844 
   4845 /*===========================================================================
   4846  * FUNCTION   : cancelPicture
   4847  *
   4848  * DESCRIPTION: cancel picture impl
   4849  *
   4850  * PARAMETERS : none
   4851  *
   4852  * RETURN     : int32_t type of status
   4853  *              NO_ERROR  -- success
   4854  *              none-zero failure code
   4855  *==========================================================================*/
   4856 int QCamera2HardwareInterface::cancelPicture()
   4857 {
   4858     waitDeferredWork(mReprocJob);
   4859     waitDeferredWork(mJpegJob);
   4860 
   4861     //stop post processor
   4862     m_postprocessor.stop();
   4863 
   4864     unconfigureAdvancedCapture();
   4865     LOGH("Enable display frames again");
   4866     setDisplaySkip(FALSE);
   4867 
   4868     if (!mLongshotEnabled) {
   4869         m_perfLock.lock_rel();
   4870     }
   4871 
   4872     if (mParameters.isZSLMode()) {
   4873         QCameraPicChannel *pPicChannel = NULL;
   4874         if (mParameters.getofflineRAW()) {
   4875             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
   4876         } else {
   4877             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   4878         }
   4879         if (NULL != pPicChannel) {
   4880             pPicChannel->cancelPicture();
   4881             stopRAWChannel();
   4882             stopAdvancedCapture(pPicChannel);
   4883         }
   4884     } else {
   4885 
   4886         // normal capture case
   4887         if (mParameters.isJpegPictureFormat() ||
   4888             mParameters.isNV16PictureFormat() ||
   4889             mParameters.isNV21PictureFormat()) {
   4890             stopChannel(QCAMERA_CH_TYPE_CAPTURE);
   4891             delChannel(QCAMERA_CH_TYPE_CAPTURE);
   4892         } else {
   4893             stopChannel(QCAMERA_CH_TYPE_RAW);
   4894             delChannel(QCAMERA_CH_TYPE_RAW);
   4895         }
   4896     }
   4897 
   4898     return NO_ERROR;
   4899 }
   4900 
   4901 /*===========================================================================
   4902  * FUNCTION   : captureDone
   4903  *
   4904  * DESCRIPTION: Function called when the capture is completed before encoding
   4905  *
   4906  * PARAMETERS : none
   4907  *
   4908  * RETURN     : none
   4909  *==========================================================================*/
   4910 void QCamera2HardwareInterface::captureDone()
   4911 {
   4912     qcamera_sm_internal_evt_payload_t *payload =
   4913        (qcamera_sm_internal_evt_payload_t *)
   4914        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   4915     if (NULL != payload) {
   4916         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   4917         payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
   4918         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   4919         if (rc != NO_ERROR) {
   4920             LOGE("processEvt ZSL capture done failed");
   4921             free(payload);
   4922             payload = NULL;
   4923         }
   4924     } else {
   4925         LOGE("No memory for ZSL capture done event");
   4926     }
   4927 }
   4928 
   4929 /*===========================================================================
   4930  * FUNCTION   : Live_Snapshot_thread
   4931  *
   4932  * DESCRIPTION: Seperate thread for taking live snapshot during recording
   4933  *
   4934  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
   4935  *
   4936  * RETURN     : none
   4937  *==========================================================================*/
   4938 void* Live_Snapshot_thread (void* data)
   4939 {
   4940 
   4941     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
   4942     if (!hw) {
   4943         LOGE("take_picture_thread: NULL camera device");
   4944         return (void *)BAD_VALUE;
   4945     }
   4946     hw->takeLiveSnapshot_internal();
   4947     return (void* )NULL;
   4948 }
   4949 
   4950 /*===========================================================================
   4951  * FUNCTION   : Int_Pic_thread
   4952  *
   4953  * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
   4954  *
   4955  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
   4956  *
   4957  * RETURN     : none
   4958  *==========================================================================*/
   4959 void* Int_Pic_thread (void* data)
   4960 {
   4961     int rc = NO_ERROR;
   4962 
   4963     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
   4964 
   4965     if (!hw) {
   4966         LOGE("take_picture_thread: NULL camera device");
   4967         return (void *)BAD_VALUE;
   4968     }
   4969 
   4970     bool JpegMemOpt = false;
   4971     char raw_format[PROPERTY_VALUE_MAX];
   4972 
   4973     memset(raw_format, 0, sizeof(raw_format));
   4974 
   4975     rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
   4976     if (rc == NO_ERROR) {
   4977         hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
   4978     } else {
   4979         //Snapshot attempt not successful, we need to do cleanup here
   4980         hw->clearIntPendingEvents();
   4981     }
   4982 
   4983     return (void* )NULL;
   4984 }
   4985 
   4986 /*===========================================================================
   4987  * FUNCTION   : takeLiveSnapshot
   4988  *
   4989  * DESCRIPTION: take live snapshot during recording
   4990  *
   4991  * PARAMETERS : none
   4992  *
   4993  * RETURN     : int32_t type of status
   4994  *              NO_ERROR  -- success
   4995  *              none-zero failure code
   4996  *==========================================================================*/
   4997 int QCamera2HardwareInterface::takeLiveSnapshot()
   4998 {
   4999     int rc = NO_ERROR;
   5000     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
   5001     if (!rc) {
   5002         pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
   5003     }
   5004     return rc;
   5005 }
   5006 
   5007 /*===========================================================================
   5008  * FUNCTION   : takePictureInternal
   5009  *
   5010  * DESCRIPTION: take snapshot triggered by backend
   5011  *
   5012  * PARAMETERS : none
   5013  *
   5014  * RETURN     : int32_t type of status
   5015  *              NO_ERROR  -- success
   5016  *              none-zero failure code
   5017  *==========================================================================*/
   5018 int QCamera2HardwareInterface::takePictureInternal()
   5019 {
   5020     int rc = NO_ERROR;
   5021     rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
   5022     if (!rc) {
   5023         pthread_setname_np(mIntPicThread, "CAM_IntPic");
   5024     }
   5025     return rc;
   5026 }
   5027 
   5028 /*===========================================================================
   5029  * FUNCTION   : checkIntPicPending
   5030  *
   5031  * DESCRIPTION: timed wait for jpeg completion event, and send
   5032  *                        back completion event to backend
   5033  *
   5034  * PARAMETERS : none
   5035  *
   5036  * RETURN     : none
   5037  *==========================================================================*/
   5038 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
   5039 {
   5040     bool bSendToBackend = true;
   5041     cam_int_evt_params_t params;
   5042     int rc = NO_ERROR;
   5043 
   5044     struct timespec   ts;
   5045     struct timeval    tp;
   5046     gettimeofday(&tp, NULL);
   5047     ts.tv_sec  = tp.tv_sec + 5;
   5048     ts.tv_nsec = tp.tv_usec * 1000;
   5049 
   5050     if (true == m_bIntJpegEvtPending ||
   5051         (true == m_bIntRawEvtPending)) {
   5052         //Waiting in HAL for snapshot taken notification
   5053         pthread_mutex_lock(&m_int_lock);
   5054         rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
   5055         if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
   5056             //Hit a timeout, or some spurious activity
   5057             bSendToBackend = false;
   5058         }
   5059 
   5060         if (true == m_bIntJpegEvtPending) {
   5061             params.event_type = 0;
   5062             mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
   5063         } else if (true == m_bIntRawEvtPending) {
   5064             params.event_type = 1;
   5065             mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
   5066         }
   5067         pthread_mutex_unlock(&m_int_lock);
   5068 
   5069         if (true == m_bIntJpegEvtPending) {
   5070             //Attempting to restart preview after taking JPEG snapshot
   5071             lockAPI();
   5072             rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
   5073             unlockAPI();
   5074             m_postprocessor.setJpegMemOpt(JpegMemOpt);
   5075         } else if (true == m_bIntRawEvtPending) {
   5076             //Attempting to restart preview after taking RAW snapshot
   5077             stopChannel(QCAMERA_CH_TYPE_RAW);
   5078             delChannel(QCAMERA_CH_TYPE_RAW);
   5079             //restoring the old raw format
   5080             property_set("persist.camera.raw.format", raw_format);
   5081         }
   5082 
   5083         if (true == bSendToBackend) {
   5084             //send event back to server with the file path
   5085             params.dim = m_postprocessor.m_dst_dim;
   5086             memcpy(&params.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
   5087             memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
   5088             params.size = mBackendFileSize;
   5089             rc = mParameters.setIntEvent(params);
   5090         }
   5091 
   5092         clearIntPendingEvents();
   5093     }
   5094 
   5095     return;
   5096 }
   5097 
   5098 /*===========================================================================
   5099  * FUNCTION   : takeBackendPic_internal
   5100  *
   5101  * DESCRIPTION: take snapshot triggered by backend
   5102  *
   5103  * PARAMETERS : none
   5104  *
   5105  * RETURN     : int32_t type of status
   5106  *              NO_ERROR  -- success
   5107  *              none-zero failure code
   5108  *==========================================================================*/
   5109 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
   5110 {
   5111     int rc = NO_ERROR;
   5112     qcamera_api_result_t apiResult;
   5113 
   5114     lockAPI();
   5115     //Set rotation value from user settings as Jpeg rotation
   5116     //to configure back-end modules.
   5117     mParameters.setJpegRotation(mParameters.getRotation());
   5118 
   5119     setRetroPicture(0);
   5120     /* Prepare snapshot in case LED needs to be flashed */
   5121     if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
   5122         // Start Preparing for normal Frames
   5123         LOGH("Start Prepare Snapshot");
   5124         /* Prepare snapshot in case LED needs to be flashed */
   5125         rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
   5126         if (rc == NO_ERROR) {
   5127             waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
   5128             rc = apiResult.status;
   5129         }
   5130         LOGH("Prep Snapshot done rc = %d", rc);
   5131         mPrepSnapRun = true;
   5132     }
   5133     unlockAPI();
   5134 
   5135     if (true == m_bIntJpegEvtPending) {
   5136         //Attempting to take JPEG snapshot
   5137         if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   5138             LOGE("Init PProc Deferred work failed");
   5139             return UNKNOWN_ERROR;
   5140         }
   5141         *JpegMemOpt = m_postprocessor.getJpegMemOpt();
   5142         m_postprocessor.setJpegMemOpt(false);
   5143 
   5144         /* capture */
   5145         lockAPI();
   5146         LOGH("Capturing internal snapshot");
   5147         rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
   5148         if (rc == NO_ERROR) {
   5149             waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
   5150             rc = apiResult.status;
   5151         }
   5152         unlockAPI();
   5153     } else if (true == m_bIntRawEvtPending) {
   5154         //Attempting to take RAW snapshot
   5155         (void)JpegMemOpt;
   5156         stopPreview();
   5157 
   5158         //getting the existing raw format type
   5159         property_get("persist.camera.raw.format", raw_format, "17");
   5160         //setting it to a default know value for this task
   5161         property_set("persist.camera.raw.format", "18");
   5162 
   5163         rc = addChannel(QCAMERA_CH_TYPE_RAW);
   5164         if (rc == NO_ERROR) {
   5165             // start postprocessor
   5166             if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   5167                 LOGE("Init PProc Deferred work failed");
   5168                 return UNKNOWN_ERROR;
   5169             }
   5170             rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
   5171             if (rc != NO_ERROR) {
   5172                 LOGE("cannot start postprocessor");
   5173                 delChannel(QCAMERA_CH_TYPE_RAW);
   5174                 return rc;
   5175             }
   5176 
   5177             rc = startChannel(QCAMERA_CH_TYPE_RAW);
   5178             if (rc != NO_ERROR) {
   5179                 LOGE("cannot start raw channel");
   5180                 m_postprocessor.stop();
   5181                 delChannel(QCAMERA_CH_TYPE_RAW);
   5182                 return rc;
   5183             }
   5184         } else {
   5185             LOGE("cannot add raw channel");
   5186             return rc;
   5187         }
   5188     }
   5189 
   5190     return rc;
   5191 }
   5192 
   5193 /*===========================================================================
   5194  * FUNCTION   : clearIntPendingEvents
   5195  *
   5196  * DESCRIPTION: clear internal pending events pertaining to backend
   5197  *                        snapshot requests
   5198  *
   5199  * PARAMETERS : none
   5200  *
   5201  * RETURN     : int32_t type of status
   5202  *              NO_ERROR  -- success
   5203  *              none-zero failure code
   5204  *==========================================================================*/
   5205 void QCamera2HardwareInterface::clearIntPendingEvents()
   5206 {
   5207     int rc = NO_ERROR;
   5208 
   5209     if (true == m_bIntRawEvtPending) {
   5210         preparePreview();
   5211         startPreview();
   5212     }
   5213     if (true == m_bIntJpegEvtPending) {
   5214         if (false == mParameters.isZSLMode()) {
   5215             lockAPI();
   5216             rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
   5217             unlockAPI();
   5218         }
   5219     }
   5220 
   5221     pthread_mutex_lock(&m_int_lock);
   5222     if (true == m_bIntJpegEvtPending) {
   5223         m_bIntJpegEvtPending = false;
   5224     } else if (true == m_bIntRawEvtPending) {
   5225         m_bIntRawEvtPending = false;
   5226     }
   5227     pthread_mutex_unlock(&m_int_lock);
   5228     return;
   5229 }
   5230 
   5231 /*===========================================================================
   5232  * FUNCTION   : takeLiveSnapshot_internal
   5233  *
   5234  * DESCRIPTION: take live snapshot during recording
   5235  *
   5236  * PARAMETERS : none
   5237  *
   5238  * RETURN     : int32_t type of status
   5239  *              NO_ERROR  -- success
   5240  *              none-zero failure code
   5241  *==========================================================================*/
   5242 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
   5243 {
   5244     int rc = NO_ERROR;
   5245 
   5246     QCameraChannel *pChannel = NULL;
   5247 
   5248     //Set rotation value from user settings as Jpeg rotation
   5249     //to configure back-end modules.
   5250     mParameters.setJpegRotation(mParameters.getRotation());
   5251 
   5252     // Configure advanced capture
   5253     rc = configureAdvancedCapture();
   5254     if (rc != NO_ERROR) {
   5255         LOGE("Unsupported capture call");
   5256         goto end;
   5257     }
   5258 
   5259     if (isLowPowerMode()) {
   5260         pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
   5261     } else {
   5262         pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   5263     }
   5264 
   5265     if (NULL == pChannel) {
   5266         LOGE("Snapshot/Video channel not initialized");
   5267         rc = NO_INIT;
   5268         goto end;
   5269     }
   5270 
   5271     DeferWorkArgs args;
   5272     memset(&args, 0, sizeof(DeferWorkArgs));
   5273 
   5274     args.pprocArgs = pChannel;
   5275 
   5276     // No need to wait for mInitPProcJob here, because it was
   5277     // queued in startPreview, and will definitely be processed before
   5278     // mReprocJob can begin.
   5279     mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   5280             args);
   5281     if (mReprocJob == 0) {
   5282         LOGE("Failed to queue CMD_DEF_PPROC_START");
   5283         rc = -ENOMEM;
   5284         goto end;
   5285     }
   5286 
   5287     // Create JPEG session
   5288     mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   5289             args);
   5290     if (mJpegJob == 0) {
   5291         LOGE("Failed to queue CREATE_JPEG_SESSION");
   5292         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5293             LOGE("Reprocess Deferred work was failed");
   5294         }
   5295         m_postprocessor.stop();
   5296         rc = -ENOMEM;
   5297         goto end;
   5298     }
   5299 
   5300     if (isLowPowerMode()) {
   5301         mm_camera_req_buf_t buf;
   5302         memset(&buf, 0x0, sizeof(buf));
   5303         buf.type = MM_CAMERA_REQ_SUPER_BUF;
   5304         buf.num_buf_requested = 1;
   5305         rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
   5306         goto end;
   5307     }
   5308 
   5309     //Disable reprocess for 4K liveshot case
   5310     if (!mParameters.is4k2kVideoResolution()) {
   5311         rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
   5312         if (rc != NO_ERROR) {
   5313             LOGE("online rotation failed");
   5314             if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5315                 LOGE("Reprocess Deferred work was failed");
   5316             }
   5317             if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   5318                 LOGE("Jpeg Deferred work was failed");
   5319             }
   5320             m_postprocessor.stop();
   5321             return rc;
   5322         }
   5323     }
   5324 
   5325     if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
   5326         QCameraStream *pStream = NULL;
   5327         for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
   5328             pStream = pChannel->getStreamByIndex(i);
   5329             if ((NULL != pStream) &&
   5330                     (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
   5331                 break;
   5332             }
   5333         }
   5334         if (pStream != NULL) {
   5335             LOGD("REQUEST_FRAMES event for TNR snapshot");
   5336             cam_stream_parm_buffer_t param;
   5337             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
   5338             param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
   5339             param.frameRequest.enableStream = 1;
   5340             rc = pStream->setParameter(param);
   5341             if (rc != NO_ERROR) {
   5342                 LOGE("Stream Event REQUEST_FRAMES failed");
   5343             }
   5344             goto end;
   5345         }
   5346     }
   5347 
   5348     // start snapshot channel
   5349     if ((rc == NO_ERROR) && (NULL != pChannel)) {
   5350         // Do not link metadata stream for 4K2k resolution
   5351         // as CPP processing would be done on snapshot stream and not
   5352         // reprocess stream
   5353         if (!mParameters.is4k2kVideoResolution()) {
   5354             // Find and try to link a metadata stream from preview channel
   5355             QCameraChannel *pMetaChannel = NULL;
   5356             QCameraStream *pMetaStream = NULL;
   5357             QCameraStream *pPreviewStream = NULL;
   5358 
   5359             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   5360                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   5361                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
   5362                 QCameraStream *pStream = NULL;
   5363                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   5364                     pStream = pMetaChannel->getStreamByIndex(i);
   5365                     if (NULL != pStream) {
   5366                         if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
   5367                             pMetaStream = pStream;
   5368                         } else if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
   5369                             pPreviewStream = pStream;
   5370                         }
   5371                     }
   5372                 }
   5373             }
   5374 
   5375             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   5376                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   5377                 if (NO_ERROR != rc) {
   5378                     LOGE("Metadata stream link failed %d", rc);
   5379                 }
   5380             }
   5381             if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
   5382                 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
   5383                 if (NO_ERROR != rc) {
   5384                     LOGE("Preview stream link failed %d", rc);
   5385                 }
   5386             }
   5387         }
   5388         rc = pChannel->start();
   5389     }
   5390 
   5391 end:
   5392     if (rc != NO_ERROR) {
   5393         rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
   5394         rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
   5395     }
   5396     return rc;
   5397 }
   5398 
   5399 /*===========================================================================
   5400  * FUNCTION   : cancelLiveSnapshot
   5401  *
   5402  * DESCRIPTION: cancel current live snapshot request
   5403  *
   5404  * PARAMETERS : none
   5405  *
   5406  * RETURN     : int32_t type of status
   5407  *              NO_ERROR  -- success
   5408  *              none-zero failure code
   5409  *==========================================================================*/
   5410 int QCamera2HardwareInterface::cancelLiveSnapshot()
   5411 {
   5412     int rc = NO_ERROR;
   5413 
   5414     unconfigureAdvancedCapture();
   5415     LOGH("Enable display frames again");
   5416     setDisplaySkip(FALSE);
   5417 
   5418     if (!mLongshotEnabled) {
   5419         m_perfLock.lock_rel();
   5420     }
   5421 
   5422     if (mLiveSnapshotThread != 0) {
   5423         pthread_join(mLiveSnapshotThread,NULL);
   5424         mLiveSnapshotThread = 0;
   5425     }
   5426 
   5427     //stop post processor
   5428     m_postprocessor.stop();
   5429 
   5430     // stop snapshot channel
   5431     if (!mParameters.isTNRSnapshotEnabled()) {
   5432         rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   5433     } else {
   5434         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   5435         if (NULL != pChannel) {
   5436             QCameraStream *pStream = NULL;
   5437             for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
   5438                 pStream = pChannel->getStreamByIndex(i);
   5439                 if ((NULL != pStream) &&
   5440                         (CAM_STREAM_TYPE_SNAPSHOT ==
   5441                         pStream->getMyType())) {
   5442                     break;
   5443                 }
   5444             }
   5445             if (pStream != NULL) {
   5446                 LOGD("REQUEST_FRAMES event for TNR snapshot");
   5447                 cam_stream_parm_buffer_t param;
   5448                 memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
   5449                 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
   5450                 param.frameRequest.enableStream = 0;
   5451                 rc = pStream->setParameter(param);
   5452                 if (rc != NO_ERROR) {
   5453                     LOGE("Stream Event REQUEST_FRAMES failed");
   5454                 }
   5455             }
   5456         }
   5457     }
   5458 
   5459     return rc;
   5460 }
   5461 
   5462 /*===========================================================================
   5463  * FUNCTION   : putParameters
   5464  *
   5465  * DESCRIPTION: put parameters string impl
   5466  *
   5467  * PARAMETERS :
   5468  *   @parms   : parameters string to be released
   5469  *
   5470  * RETURN     : int32_t type of status
   5471  *              NO_ERROR  -- success
   5472  *              none-zero failure code
   5473  *==========================================================================*/
   5474 int QCamera2HardwareInterface::putParameters(char *parms)
   5475 {
   5476     free(parms);
   5477     return NO_ERROR;
   5478 }
   5479 
   5480 /*===========================================================================
   5481  * FUNCTION   : sendCommand
   5482  *
   5483  * DESCRIPTION: send command impl
   5484  *
   5485  * PARAMETERS :
   5486  *   @command : command to be executed
   5487  *   @arg1    : optional argument 1
   5488  *   @arg2    : optional argument 2
   5489  *
   5490  * RETURN     : int32_t type of status
   5491  *              NO_ERROR  -- success
   5492  *              none-zero failure code
   5493  *==========================================================================*/
   5494 int QCamera2HardwareInterface::sendCommand(int32_t command,
   5495         __unused int32_t &arg1, __unused int32_t &arg2)
   5496 {
   5497     int rc = NO_ERROR;
   5498 
   5499     switch (command) {
   5500 #ifndef VANILLA_HAL
   5501     case CAMERA_CMD_LONGSHOT_ON:
   5502         m_perfLock.lock_acq();
   5503         arg1 = arg2 = 0;
   5504         // Longshot can only be enabled when image capture
   5505         // is not active.
   5506         if ( !m_stateMachine.isCaptureRunning() ) {
   5507             LOGI("Longshot Enabled");
   5508             mLongshotEnabled = true;
   5509             rc = mParameters.setLongshotEnable(mLongshotEnabled);
   5510 
   5511             // Due to recent buffer count optimizations
   5512             // ZSL might run with considerably less buffers
   5513             // when not in longshot mode. Preview needs to
   5514             // restart in this case.
   5515             if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
   5516                 QCameraChannel *pChannel = NULL;
   5517                 QCameraStream *pSnapStream = NULL;
   5518                 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   5519                 if (NULL != pChannel) {
   5520                     QCameraStream *pStream = NULL;
   5521                     for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
   5522                         pStream = pChannel->getStreamByIndex(i);
   5523                         if (pStream != NULL) {
   5524                             if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
   5525                                 pSnapStream = pStream;
   5526                                 break;
   5527                             }
   5528                         }
   5529                     }
   5530                     if (NULL != pSnapStream) {
   5531                         uint8_t required = 0;
   5532                         required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
   5533                         if (pSnapStream->getBufferCount() < required) {
   5534                             // We restart here, to reset the FPS and no
   5535                             // of buffers as per the requirement of longshot usecase.
   5536                             arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
   5537                             if (getRelatedCamSyncInfo()->sync_control ==
   5538                                     CAM_SYNC_RELATED_SENSORS_ON) {
   5539                                 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
   5540                             }
   5541                         }
   5542                     }
   5543                 }
   5544             }
   5545             //
   5546             mPrepSnapRun = false;
   5547             mCACDoneReceived = FALSE;
   5548         } else {
   5549             rc = NO_INIT;
   5550         }
   5551         break;
   5552     case CAMERA_CMD_LONGSHOT_OFF:
   5553         m_perfLock.lock_rel();
   5554         if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
   5555             cancelPicture();
   5556             processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
   5557             QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   5558             if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
   5559                 mCameraHandle->ops->stop_zsl_snapshot(
   5560                         mCameraHandle->camera_handle,
   5561                         pZSLChannel->getMyHandle());
   5562             }
   5563         }
   5564         mPrepSnapRun = false;
   5565         LOGI("Longshot Disabled");
   5566         mLongshotEnabled = false;
   5567         rc = mParameters.setLongshotEnable(mLongshotEnabled);
   5568         mCACDoneReceived = FALSE;
   5569         break;
   5570     case CAMERA_CMD_HISTOGRAM_ON:
   5571     case CAMERA_CMD_HISTOGRAM_OFF:
   5572         rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
   5573         LOGH("Histogram -> %s",
   5574               mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
   5575         break;
   5576 #endif
   5577     case CAMERA_CMD_START_FACE_DETECTION:
   5578     case CAMERA_CMD_STOP_FACE_DETECTION:
   5579         mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
   5580         rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
   5581         LOGH("FaceDetection -> %s",
   5582               mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
   5583         break;
   5584 #ifndef VANILLA_HAL
   5585     case CAMERA_CMD_HISTOGRAM_SEND_DATA:
   5586 #endif
   5587     default:
   5588         rc = NO_ERROR;
   5589         break;
   5590     }
   5591     return rc;
   5592 }
   5593 
   5594 /*===========================================================================
   5595  * FUNCTION   : registerFaceImage
   5596  *
   5597  * DESCRIPTION: register face image impl
   5598  *
   5599  * PARAMETERS :
   5600  *   @img_ptr : ptr to image buffer
   5601  *   @config  : ptr to config struct about input image info
   5602  *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
   5603  *
   5604  * RETURN     : int32_t type of status
   5605  *              NO_ERROR  -- success
   5606  *              none-zero failure code
   5607  *==========================================================================*/
   5608 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
   5609                                                  cam_pp_offline_src_config_t *config,
   5610                                                  int32_t &faceID)
   5611 {
   5612     int rc = NO_ERROR;
   5613     faceID = -1;
   5614 
   5615     if (img_ptr == NULL || config == NULL) {
   5616         LOGE("img_ptr or config is NULL");
   5617         return BAD_VALUE;
   5618     }
   5619 
   5620     // allocate ion memory for source image
   5621     QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   5622     if (imgBuf == NULL) {
   5623         LOGE("Unable to new heap memory obj for image buf");
   5624         return NO_MEMORY;
   5625     }
   5626 
   5627     rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE);
   5628     if (rc < 0) {
   5629         LOGE("Unable to allocate heap memory for image buf");
   5630         delete imgBuf;
   5631         return NO_MEMORY;
   5632     }
   5633 
   5634     void *pBufPtr = imgBuf->getPtr(0);
   5635     if (pBufPtr == NULL) {
   5636         LOGE("image buf is NULL");
   5637         imgBuf->deallocate();
   5638         delete imgBuf;
   5639         return NO_MEMORY;
   5640     }
   5641     memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
   5642 
   5643     cam_pp_feature_config_t pp_feature;
   5644     memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
   5645     pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
   5646     QCameraReprocessChannel *pChannel =
   5647         addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
   5648 
   5649     if (pChannel == NULL) {
   5650         LOGE("fail to add offline reprocess channel");
   5651         imgBuf->deallocate();
   5652         delete imgBuf;
   5653         return UNKNOWN_ERROR;
   5654     }
   5655 
   5656     rc = pChannel->start();
   5657     if (rc != NO_ERROR) {
   5658         LOGE("Cannot start reprocess channel");
   5659         imgBuf->deallocate();
   5660         delete imgBuf;
   5661         delete pChannel;
   5662         return rc;
   5663     }
   5664 
   5665     ssize_t bufSize = imgBuf->getSize(0);
   5666     if (BAD_INDEX != bufSize) {
   5667         rc = pChannel->doReprocess(imgBuf->getFd(0), (size_t)bufSize, faceID);
   5668     } else {
   5669         LOGE("Failed to retrieve buffer size (bad index)");
   5670         return UNKNOWN_ERROR;
   5671     }
   5672 
   5673     // done with register face image, free imgbuf and delete reprocess channel
   5674     imgBuf->deallocate();
   5675     delete imgBuf;
   5676     imgBuf = NULL;
   5677     pChannel->stop();
   5678     delete pChannel;
   5679     pChannel = NULL;
   5680 
   5681     return rc;
   5682 }
   5683 
   5684 /*===========================================================================
   5685  * FUNCTION   : release
   5686  *
   5687  * DESCRIPTION: release camera resource impl
   5688  *
   5689  * PARAMETERS : none
   5690  *
   5691  * RETURN     : int32_t type of status
   5692  *              NO_ERROR  -- success
   5693  *              none-zero failure code
   5694  *==========================================================================*/
   5695 int QCamera2HardwareInterface::release()
   5696 {
   5697     // stop and delete all channels
   5698     for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
   5699         if (m_channels[i] != NULL) {
   5700             stopChannel((qcamera_ch_type_enum_t)i);
   5701             delChannel((qcamera_ch_type_enum_t)i);
   5702         }
   5703     }
   5704 
   5705     return NO_ERROR;
   5706 }
   5707 
   5708 /*===========================================================================
   5709  * FUNCTION   : dump
   5710  *
   5711  * DESCRIPTION: camera status dump impl
   5712  *
   5713  * PARAMETERS :
   5714  *   @fd      : fd for the buffer to be dumped with camera status
   5715  *
   5716  * RETURN     : int32_t type of status
   5717  *              NO_ERROR  -- success
   5718  *              none-zero failure code
   5719  *==========================================================================*/
   5720 int QCamera2HardwareInterface::dump(int fd)
   5721 {
   5722     dprintf(fd, "\n Camera HAL information Begin \n");
   5723     dprintf(fd, "Camera ID: %d \n", mCameraId);
   5724     dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
   5725     dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
   5726     dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
   5727     dprintf(fd, "\n Camera HAL information End \n");
   5728 
   5729     /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
   5730        debug level property */
   5731     mParameters.updateDebugLevel();
   5732     return NO_ERROR;
   5733 }
   5734 
   5735 /*===========================================================================
   5736  * FUNCTION   : processAPI
   5737  *
   5738  * DESCRIPTION: process API calls from upper layer
   5739  *
   5740  * PARAMETERS :
   5741  *   @api         : API to be processed
   5742  *   @api_payload : ptr to API payload if any
   5743  *
   5744  * RETURN     : int32_t type of status
   5745  *              NO_ERROR  -- success
   5746  *              none-zero failure code
   5747  *==========================================================================*/
   5748 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
   5749 {
   5750     int ret = DEAD_OBJECT;
   5751 
   5752     if (m_smThreadActive) {
   5753         ret = m_stateMachine.procAPI(api, api_payload);
   5754     }
   5755 
   5756     return ret;
   5757 }
   5758 
   5759 /*===========================================================================
   5760  * FUNCTION   : processEvt
   5761  *
   5762  * DESCRIPTION: process Evt from backend via mm-camera-interface
   5763  *
   5764  * PARAMETERS :
   5765  *   @evt         : event type to be processed
   5766  *   @evt_payload : ptr to event payload if any
   5767  *
   5768  * RETURN     : int32_t type of status
   5769  *              NO_ERROR  -- success
   5770  *              none-zero failure code
   5771  *==========================================================================*/
   5772 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
   5773 {
   5774     return m_stateMachine.procEvt(evt, evt_payload);
   5775 }
   5776 
   5777 /*===========================================================================
   5778  * FUNCTION   : processSyncEvt
   5779  *
   5780  * DESCRIPTION: process synchronous Evt from backend
   5781  *
   5782  * PARAMETERS :
   5783  *   @evt         : event type to be processed
   5784  *   @evt_payload : ptr to event payload if any
   5785  *
   5786  * RETURN     : int32_t type of status
   5787  *              NO_ERROR  -- success
   5788  *              none-zero failure code
   5789  *==========================================================================*/
   5790 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
   5791 {
   5792     int rc = NO_ERROR;
   5793 
   5794     pthread_mutex_lock(&m_evtLock);
   5795     rc =  processEvt(evt, evt_payload);
   5796     if (rc == NO_ERROR) {
   5797         memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
   5798         while (m_evtResult.request_api != evt) {
   5799             pthread_cond_wait(&m_evtCond, &m_evtLock);
   5800         }
   5801         rc =  m_evtResult.status;
   5802     }
   5803     pthread_mutex_unlock(&m_evtLock);
   5804 
   5805     return rc;
   5806 }
   5807 
   5808 /*===========================================================================
   5809  * FUNCTION   : evtHandle
   5810  *
   5811  * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
   5812  *
   5813  * PARAMETERS :
   5814  *   @camera_handle : event type to be processed
   5815  *   @evt           : ptr to event
   5816  *   @user_data     : user data ptr
   5817  *
   5818  * RETURN     : none
   5819  *==========================================================================*/
   5820 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
   5821                                           mm_camera_event_t *evt,
   5822                                           void *user_data)
   5823 {
   5824     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
   5825     if (obj && evt) {
   5826         mm_camera_event_t *payload =
   5827             (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
   5828         if (NULL != payload) {
   5829             *payload = *evt;
   5830             //peek into the event, if this is an eztune event from server,
   5831             //then we don't need to post it to the SM Qs, we shud directly
   5832             //spawn a thread and get the job done (jpeg or raw snapshot)
   5833             switch (payload->server_event_type) {
   5834                 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
   5835                     //Received JPEG trigger from eztune
   5836                     if (false == obj->m_bIntJpegEvtPending) {
   5837                         pthread_mutex_lock(&obj->m_int_lock);
   5838                         obj->m_bIntJpegEvtPending = true;
   5839                         pthread_mutex_unlock(&obj->m_int_lock);
   5840                         obj->takePictureInternal();
   5841                     }
   5842                     free(payload);
   5843                     break;
   5844                 case CAM_EVENT_TYPE_INT_TAKE_RAW:
   5845                     //Received RAW trigger from eztune
   5846                     if (false == obj->m_bIntRawEvtPending) {
   5847                         pthread_mutex_lock(&obj->m_int_lock);
   5848                         obj->m_bIntRawEvtPending = true;
   5849                         pthread_mutex_unlock(&obj->m_int_lock);
   5850                         obj->takePictureInternal();
   5851                     }
   5852                     free(payload);
   5853                     break;
   5854                 case CAM_EVENT_TYPE_DAEMON_DIED:
   5855                     {
   5856                         Mutex::Autolock l(obj->mDefLock);
   5857                         obj->mDefCond.broadcast();
   5858                         LOGH("broadcast mDefCond signal\n");
   5859                     }
   5860                 default:
   5861                     obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
   5862                     break;
   5863             }
   5864         }
   5865     } else {
   5866         LOGE("NULL user_data");
   5867     }
   5868 }
   5869 
   5870 /*===========================================================================
   5871  * FUNCTION   : jpegEvtHandle
   5872  *
   5873  * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
   5874  *
   5875  * PARAMETERS :
   5876  *   @status    : status of jpeg job
   5877  *   @client_hdl: jpeg client handle
   5878  *   @jobId     : jpeg job Id
   5879  *   @p_ouput   : ptr to jpeg output result struct
   5880  *   @userdata  : user data ptr
   5881  *
   5882  * RETURN     : none
   5883  *==========================================================================*/
   5884 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
   5885                                               uint32_t /*client_hdl*/,
   5886                                               uint32_t jobId,
   5887                                               mm_jpeg_output_t *p_output,
   5888                                               void *userdata)
   5889 {
   5890     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
   5891     if (obj) {
   5892         qcamera_jpeg_evt_payload_t *payload =
   5893             (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
   5894         if (NULL != payload) {
   5895             memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
   5896             payload->status = status;
   5897             payload->jobId = jobId;
   5898             if (p_output != NULL) {
   5899                 payload->out_data = *p_output;
   5900             }
   5901             obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
   5902         }
   5903     } else {
   5904         LOGE("NULL user_data");
   5905     }
   5906 }
   5907 
   5908 /*===========================================================================
   5909  * FUNCTION   : thermalEvtHandle
   5910  *
   5911  * DESCRIPTION: routine to handle thermal event notification
   5912  *
   5913  * PARAMETERS :
   5914  *   @level      : thermal level
   5915  *   @userdata   : userdata passed in during registration
   5916  *   @data       : opaque data from thermal client
   5917  *
   5918  * RETURN     : int32_t type of status
   5919  *              NO_ERROR  -- success
   5920  *              none-zero failure code
   5921  *==========================================================================*/
   5922 int QCamera2HardwareInterface::thermalEvtHandle(
   5923         qcamera_thermal_level_enum_t *level, void *userdata, void *data)
   5924 {
   5925     if (!mCameraOpened) {
   5926         LOGH("Camera is not opened, no need to handle thermal evt");
   5927         return NO_ERROR;
   5928     }
   5929 
   5930     // Make sure thermal events are logged
   5931     LOGH("level = %d, userdata = %p, data = %p",
   5932          *level, userdata, data);
   5933     //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
   5934     // becomes an aync call. This also means we can only pass payload
   5935     // by value, not by address.
   5936     return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
   5937 }
   5938 
   5939 /*===========================================================================
   5940  * FUNCTION   : sendEvtNotify
   5941  *
   5942  * DESCRIPTION: send event notify to notify thread
   5943  *
   5944  * PARAMETERS :
   5945  *   @msg_type: msg type to be sent
   5946  *   @ext1    : optional extension1
   5947  *   @ext2    : optional extension2
   5948  *
   5949  * RETURN     : int32_t type of status
   5950  *              NO_ERROR  -- success
   5951  *              none-zero failure code
   5952  *==========================================================================*/
   5953 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
   5954                                                  int32_t ext1,
   5955                                                  int32_t ext2)
   5956 {
   5957     qcamera_callback_argm_t cbArg;
   5958     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   5959     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
   5960     cbArg.msg_type = msg_type;
   5961     cbArg.ext1 = ext1;
   5962     cbArg.ext2 = ext2;
   5963     return m_cbNotifier.notifyCallback(cbArg);
   5964 }
   5965 
   5966 /*===========================================================================
   5967  * FUNCTION   : processAEInfo
   5968  *
   5969  * DESCRIPTION: process AE updates
   5970  *
   5971  * PARAMETERS :
   5972  *   @ae_params: current AE parameters
   5973  *
   5974  * RETURN     : None
   5975  *==========================================================================*/
   5976 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
   5977 {
   5978     mParameters.updateAEInfo(ae_params);
   5979     if (mParameters.isInstantAECEnabled()) {
   5980         // Reset Instant AEC info only if instant aec enabled.
   5981         bool bResetInstantAec = false;
   5982         if (ae_params.settled) {
   5983             // If AEC settled, reset instant AEC
   5984             bResetInstantAec = true;
   5985         } else if ((mParameters.isInstantCaptureEnabled()) &&
   5986                 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
   5987             // if AEC not settled, and instant capture enabled,
   5988             // reset instant AEC only when frame count is
   5989             // more or equal to AEC frame bound value.
   5990             bResetInstantAec = true;
   5991         } else if ((mParameters.isInstantAECEnabled()) &&
   5992                 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
   5993             // if AEC not settled, and only instant AEC enabled,
   5994             // reset instant AEC only when frame count is
   5995             // more or equal to AEC skip display frame bound value.
   5996             bResetInstantAec = true;
   5997         }
   5998 
   5999         if (bResetInstantAec) {
   6000             LOGD("setting instant AEC to false");
   6001             mParameters.setInstantAEC(false, true);
   6002             mInstantAecFrameCount = 0;
   6003         }
   6004     }
   6005     return NO_ERROR;
   6006 }
   6007 
   6008 /*===========================================================================
   6009  * FUNCTION   : processFocusPositionInfo
   6010  *
   6011  * DESCRIPTION: process AF updates
   6012  *
   6013  * PARAMETERS :
   6014  *   @cur_pos_info: current lens position
   6015  *
   6016  * RETURN     : None
   6017  *==========================================================================*/
   6018 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
   6019 {
   6020     mParameters.updateCurrentFocusPosition(cur_pos_info);
   6021     return NO_ERROR;
   6022 }
   6023 
   6024 /*===========================================================================
   6025  * FUNCTION   : processAutoFocusEvent
   6026  *
   6027  * DESCRIPTION: process auto focus event
   6028  *
   6029  * PARAMETERS :
   6030  *   @focus_data: struct containing auto focus result info
   6031  *
   6032  * RETURN     : int32_t type of status
   6033  *              NO_ERROR  -- success
   6034  *              none-zero failure code
   6035  *==========================================================================*/
   6036 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
   6037 {
   6038     int32_t ret = NO_ERROR;
   6039     LOGH("E");
   6040 
   6041     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
   6042         // Ignore focus updates
   6043         LOGH("X Secondary Camera, no need to process!! ");
   6044         return ret;
   6045     }
   6046     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   6047     LOGH("[AF_DBG]  focusMode=%d, focusState=%d",
   6048              focusMode, focus_data.focus_state);
   6049 
   6050     switch (focusMode) {
   6051     case CAM_FOCUS_MODE_AUTO:
   6052     case CAM_FOCUS_MODE_MACRO:
   6053         // ignore AF event if AF was already cancelled meanwhile
   6054         if (!mActiveAF) {
   6055             break;
   6056         }
   6057         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
   6058         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
   6059                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6060             ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
   6061             mActiveAF = false; // reset the mActiveAF in this special case
   6062             break;
   6063         }
   6064 
   6065         //while transitioning from CAF->Auto/Macro, we might receive CAF related
   6066         //events (PASSIVE_*) due to timing. Ignore such events if any.
   6067         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
   6068                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6069                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
   6070             break;
   6071         }
   6072 
   6073         //This is just an intermediate update to HAL indicating focus is in progress. No need
   6074         //to send this event to app. Same applies to INACTIVE state as well.
   6075         if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
   6076                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6077             break;
   6078         }
   6079         // update focus distance
   6080         mParameters.updateFocusDistances(&focus_data.focus_dist);
   6081 
   6082         //flush any old snapshot frames in ZSL Q which are not focused.
   6083         if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
   6084             QCameraPicChannel *pZSLChannel =
   6085                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   6086             if (NULL != pZSLChannel) {
   6087                 //flush the zsl-buffer
   6088                 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
   6089                 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
   6090                 pZSLChannel->flushSuperbuffer(flush_frame_idx);
   6091             }
   6092         }
   6093 
   6094         //send event to app finally
   6095         LOGI("Send AF DOne event to app");
   6096         ret = sendEvtNotify(CAMERA_MSG_FOCUS,
   6097                             (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
   6098         break;
   6099     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   6100     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   6101 
   6102         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
   6103         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
   6104                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6105             ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
   6106             mActiveAF = false; // reset the mActiveAF in this special case
   6107             break;
   6108         }
   6109 
   6110         //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
   6111         //process/wait for only ACTIVE_* events.
   6112         if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6113                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
   6114                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
   6115             break;
   6116         }
   6117 
   6118         //These are the AF states for which we need to send notification to app in CAF mode.
   6119         //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
   6120         //AF is triggered while in CAF mode)
   6121         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6122                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
   6123                 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
   6124                 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
   6125 
   6126             // update focus distance
   6127             mParameters.updateFocusDistances(&focus_data.focus_dist);
   6128 
   6129             if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
   6130                 QCameraPicChannel *pZSLChannel =
   6131                         (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   6132                 if (NULL != pZSLChannel) {
   6133                     //flush the zsl-buffer
   6134                     uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
   6135                     LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
   6136                     pZSLChannel->flushSuperbuffer(flush_frame_idx);
   6137                 }
   6138             }
   6139 
   6140             if (mActiveAF) {
   6141                 LOGI("Send AF Done event to app");
   6142             }
   6143             ret = sendEvtNotify(CAMERA_MSG_FOCUS,
   6144                     ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6145                     (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
   6146         }
   6147         ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
   6148                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
   6149         break;
   6150     case CAM_FOCUS_MODE_INFINITY:
   6151     case CAM_FOCUS_MODE_FIXED:
   6152     case CAM_FOCUS_MODE_EDOF:
   6153     default:
   6154         LOGH("no ops for autofocus event in focusmode %d", focusMode);
   6155         break;
   6156     }
   6157 
   6158     //Reset mActiveAF once we receive focus done event
   6159     if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
   6160             (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
   6161         mActiveAF = false;
   6162     }
   6163 
   6164     LOGH("X");
   6165     return ret;
   6166 }
   6167 
   6168 /*===========================================================================
   6169  * FUNCTION   : processZoomEvent
   6170  *
   6171  * DESCRIPTION: process zoom event
   6172  *
   6173  * PARAMETERS :
   6174  *   @crop_info : crop info as a result of zoom operation
   6175  *
   6176  * RETURN     : int32_t type of status
   6177  *              NO_ERROR  -- success
   6178  *              none-zero failure code
   6179  *==========================================================================*/
   6180 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
   6181 {
   6182     int32_t ret = NO_ERROR;
   6183 
   6184     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   6185         if (m_channels[i] != NULL) {
   6186             ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
   6187         }
   6188     }
   6189     return ret;
   6190 }
   6191 
   6192 /*===========================================================================
   6193  * FUNCTION   : processZSLCaptureDone
   6194  *
   6195  * DESCRIPTION: process ZSL capture done events
   6196  *
   6197  * PARAMETERS : None
   6198  *
   6199  * RETURN     : int32_t type of status
   6200  *              NO_ERROR  -- success
   6201  *              none-zero failure code
   6202  *==========================================================================*/
   6203 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
   6204 {
   6205     int rc = NO_ERROR;
   6206 
   6207     if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
   6208         rc = unconfigureAdvancedCapture();
   6209     }
   6210 
   6211     return rc;
   6212 }
   6213 
   6214 /*===========================================================================
   6215  * FUNCTION   : processRetroAECUnlock
   6216  *
   6217  * DESCRIPTION: process retro burst AEC unlock events
   6218  *
   6219  * PARAMETERS : None
   6220  *
   6221  * RETURN     : int32_t type of status
   6222  *              NO_ERROR  -- success
   6223  *              none-zero failure code
   6224  *==========================================================================*/
   6225 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
   6226 {
   6227     int rc = NO_ERROR;
   6228 
   6229     LOGH("LED assisted AF Release AEC Lock");
   6230     rc = mParameters.setAecLock("false");
   6231     if (NO_ERROR != rc) {
   6232         LOGE("Error setting AEC lock");
   6233         return rc;
   6234     }
   6235 
   6236     rc = mParameters.commitParameters();
   6237     if (NO_ERROR != rc) {
   6238         LOGE("Error during camera parameter commit");
   6239     } else {
   6240         m_bLedAfAecLock = FALSE;
   6241     }
   6242 
   6243     return rc;
   6244 }
   6245 
   6246 /*===========================================================================
   6247  * FUNCTION   : processHDRData
   6248  *
   6249  * DESCRIPTION: process HDR scene events
   6250  *
   6251  * PARAMETERS :
   6252  *   @hdr_scene : HDR scene event data
   6253  *
   6254  * RETURN     : int32_t type of status
   6255  *              NO_ERROR  -- success
   6256  *              none-zero failure code
   6257  *==========================================================================*/
   6258 int32_t QCamera2HardwareInterface::processHDRData(
   6259         __unused cam_asd_hdr_scene_data_t hdr_scene)
   6260 {
   6261     int rc = NO_ERROR;
   6262 
   6263 #ifndef VANILLA_HAL
   6264     if (hdr_scene.is_hdr_scene &&
   6265       (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
   6266       mParameters.isAutoHDREnabled()) {
   6267         m_HDRSceneEnabled = true;
   6268     } else {
   6269         m_HDRSceneEnabled = false;
   6270     }
   6271     mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
   6272 
   6273     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
   6274 
   6275         size_t data_len = sizeof(int);
   6276         size_t buffer_len = 1 *sizeof(int)       //meta type
   6277                           + 1 *sizeof(int)       //data len
   6278                           + 1 *sizeof(int);      //data
   6279         camera_memory_t *hdrBuffer = mGetMemory(-1,
   6280                                                  buffer_len,
   6281                                                  1,
   6282                                                  mCallbackCookie);
   6283         if ( NULL == hdrBuffer ) {
   6284             LOGE("Not enough memory for auto HDR data");
   6285             return NO_MEMORY;
   6286         }
   6287 
   6288         int *pHDRData = (int *)hdrBuffer->data;
   6289         if (pHDRData == NULL) {
   6290             LOGE("memory data ptr is NULL");
   6291             return UNKNOWN_ERROR;
   6292         }
   6293 
   6294         pHDRData[0] = CAMERA_META_DATA_HDR;
   6295         pHDRData[1] = (int)data_len;
   6296         pHDRData[2] = m_HDRSceneEnabled;
   6297 
   6298         qcamera_callback_argm_t cbArg;
   6299         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   6300         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   6301         cbArg.msg_type = CAMERA_MSG_META_DATA;
   6302         cbArg.data = hdrBuffer;
   6303         cbArg.user_data = hdrBuffer;
   6304         cbArg.cookie = this;
   6305         cbArg.release_cb = releaseCameraMemory;
   6306         rc = m_cbNotifier.notifyCallback(cbArg);
   6307         if (rc != NO_ERROR) {
   6308             LOGE("fail sending auto HDR notification");
   6309             hdrBuffer->release(hdrBuffer);
   6310         }
   6311     }
   6312 
   6313     LOGH("hdr_scene_data: processHDRData: %d %f",
   6314           hdr_scene.is_hdr_scene,
   6315           hdr_scene.hdr_confidence);
   6316 
   6317 #endif
   6318   return rc;
   6319 }
   6320 
   6321 /*===========================================================================
   6322  * FUNCTION   : transAwbMetaToParams
   6323  *
   6324  * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
   6325  *
   6326  * PARAMETERS :
   6327  *   @awb_params : awb params from metadata callback
   6328  *
   6329  * RETURN     : int32_t type of status
   6330  *              NO_ERROR  -- success
   6331  *              none-zero failure code
   6332  *==========================================================================*/
   6333 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
   6334 {
   6335     mParameters.updateAWBParams(awb_params);
   6336     return NO_ERROR;
   6337 }
   6338 
   6339 /*===========================================================================
   6340  * FUNCTION   : processPrepSnapshotDone
   6341  *
   6342  * DESCRIPTION: process prep snapshot done event
   6343  *
   6344  * PARAMETERS :
   6345  *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
   6346  *                           i.e. whether need future frames for capture.
   6347  *
   6348  * RETURN     : int32_t type of status
   6349  *              NO_ERROR  -- success
   6350  *              none-zero failure code
   6351  *==========================================================================*/
   6352 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
   6353                         cam_prep_snapshot_state_t prep_snapshot_state)
   6354 {
   6355     int32_t ret = NO_ERROR;
   6356     LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
   6357             prep_snapshot_state);
   6358     if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
   6359         prep_snapshot_state == NEED_FUTURE_FRAME) {
   6360         LOGH("already handled in mm-camera-intf, no ops here");
   6361         if (isRetroPicture()) {
   6362             mParameters.setAecLock("true");
   6363             mParameters.commitParameters();
   6364             m_bLedAfAecLock = TRUE;
   6365         }
   6366     }
   6367     return ret;
   6368 }
   6369 
   6370 /*===========================================================================
   6371  * FUNCTION   : processASDUpdate
   6372  *
   6373  * DESCRIPTION: process ASD update event
   6374  *
   6375  * PARAMETERS :
   6376  *   @scene: selected scene mode
   6377  *
   6378  * RETURN     : int32_t type of status
   6379  *              NO_ERROR  -- success
   6380  *              none-zero failure code
   6381  *==========================================================================*/
   6382 int32_t QCamera2HardwareInterface::processASDUpdate(
   6383         __unused cam_asd_decision_t asd_decision)
   6384 {
   6385     size_t data_len = sizeof(cam_auto_scene_t);
   6386     size_t buffer_len = 1 *sizeof(int)       //meta type
   6387                       + 1 *sizeof(int)       //data len
   6388                       + data_len;            //data
   6389     camera_memory_t *asdBuffer = mGetMemory(-1,
   6390                                              buffer_len,
   6391                                              1,
   6392                                              mCallbackCookie);
   6393     if ( NULL == asdBuffer ) {
   6394         LOGE("Not enough memory for histogram data");
   6395         return NO_MEMORY;
   6396     }
   6397 
   6398     int *pASDData = (int *)asdBuffer->data;
   6399     if (pASDData == NULL) {
   6400         LOGE("memory data ptr is NULL");
   6401         return UNKNOWN_ERROR;
   6402     }
   6403 
   6404 #ifndef VANILLA_HAL
   6405     pASDData[0] = CAMERA_META_DATA_ASD;
   6406     pASDData[1] = (int)data_len;
   6407     pASDData[2] = asd_decision.detected_scene;
   6408 
   6409     qcamera_callback_argm_t cbArg;
   6410     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   6411     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   6412     cbArg.msg_type = CAMERA_MSG_META_DATA;
   6413     cbArg.data = asdBuffer;
   6414     cbArg.user_data = asdBuffer;
   6415     cbArg.cookie = this;
   6416     cbArg.release_cb = releaseCameraMemory;
   6417     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   6418     if (rc != NO_ERROR) {
   6419         LOGE("fail sending notification");
   6420         asdBuffer->release(asdBuffer);
   6421     }
   6422 #endif
   6423     return NO_ERROR;
   6424 
   6425 }
   6426 
   6427 /*===========================================================================
   6428  * FUNCTION   : processJpegNotify
   6429  *
   6430  * DESCRIPTION: process jpeg event
   6431  *
   6432  * PARAMETERS :
   6433  *   @jpeg_evt: ptr to jpeg event payload
   6434  *
   6435  * RETURN     : int32_t type of status
   6436  *              NO_ERROR  -- success
   6437  *              none-zero failure code
   6438  *==========================================================================*/
   6439 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
   6440 {
   6441     return m_postprocessor.processJpegEvt(jpeg_evt);
   6442 }
   6443 
   6444 /*===========================================================================
   6445  * FUNCTION   : lockAPI
   6446  *
   6447  * DESCRIPTION: lock to process API
   6448  *
   6449  * PARAMETERS : none
   6450  *
   6451  * RETURN     : none
   6452  *==========================================================================*/
   6453 void QCamera2HardwareInterface::lockAPI()
   6454 {
   6455     pthread_mutex_lock(&m_lock);
   6456 }
   6457 
   6458 /*===========================================================================
   6459  * FUNCTION   : waitAPIResult
   6460  *
   6461  * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
   6462  *              return only cerntain API event type arrives
   6463  *
   6464  * PARAMETERS :
   6465  *   @api_evt : API event type
   6466  *
   6467  * RETURN     : none
   6468  *==========================================================================*/
   6469 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
   6470         qcamera_api_result_t *apiResult)
   6471 {
   6472     LOGD("wait for API result of evt (%d)", api_evt);
   6473     int resultReceived = 0;
   6474     while  (!resultReceived) {
   6475         pthread_cond_wait(&m_cond, &m_lock);
   6476         if (m_apiResultList != NULL) {
   6477             api_result_list *apiResultList = m_apiResultList;
   6478             api_result_list *apiResultListPrevious = m_apiResultList;
   6479             while (apiResultList != NULL) {
   6480                 if (apiResultList->result.request_api == api_evt) {
   6481                     resultReceived = 1;
   6482                     *apiResult = apiResultList->result;
   6483                     apiResultListPrevious->next = apiResultList->next;
   6484                     if (apiResultList == m_apiResultList) {
   6485                         m_apiResultList = apiResultList->next;
   6486                     }
   6487                     free(apiResultList);
   6488                     break;
   6489                 }
   6490                 else {
   6491                     apiResultListPrevious = apiResultList;
   6492                     apiResultList = apiResultList->next;
   6493                 }
   6494             }
   6495         }
   6496     }
   6497     LOGD("return (%d) from API result wait for evt (%d)",
   6498            apiResult->status, api_evt);
   6499 }
   6500 
   6501 
   6502 /*===========================================================================
   6503  * FUNCTION   : unlockAPI
   6504  *
   6505  * DESCRIPTION: API processing is done, unlock
   6506  *
   6507  * PARAMETERS : none
   6508  *
   6509  * RETURN     : none
   6510  *==========================================================================*/
   6511 void QCamera2HardwareInterface::unlockAPI()
   6512 {
   6513     pthread_mutex_unlock(&m_lock);
   6514 }
   6515 
   6516 /*===========================================================================
   6517  * FUNCTION   : signalAPIResult
   6518  *
   6519  * DESCRIPTION: signal condition viarable that cerntain API event type arrives
   6520  *
   6521  * PARAMETERS :
   6522  *   @result  : API result
   6523  *
   6524  * RETURN     : none
   6525  *==========================================================================*/
   6526 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
   6527 {
   6528 
   6529     pthread_mutex_lock(&m_lock);
   6530     api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
   6531     if (apiResult == NULL) {
   6532         LOGE("ERROR: malloc for api result failed, Result will not be sent");
   6533         goto malloc_failed;
   6534     }
   6535     apiResult->result = *result;
   6536     apiResult->next = NULL;
   6537     if (m_apiResultList == NULL) m_apiResultList = apiResult;
   6538     else {
   6539         api_result_list *apiResultList = m_apiResultList;
   6540         while(apiResultList->next != NULL) apiResultList = apiResultList->next;
   6541         apiResultList->next = apiResult;
   6542     }
   6543 malloc_failed:
   6544     pthread_cond_broadcast(&m_cond);
   6545     pthread_mutex_unlock(&m_lock);
   6546 }
   6547 
   6548 /*===========================================================================
   6549  * FUNCTION   : signalEvtResult
   6550  *
   6551  * DESCRIPTION: signal condition variable that certain event was processed
   6552  *
   6553  * PARAMETERS :
   6554  *   @result  : Event result
   6555  *
   6556  * RETURN     : none
   6557  *==========================================================================*/
   6558 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
   6559 {
   6560     pthread_mutex_lock(&m_evtLock);
   6561     m_evtResult = *result;
   6562     pthread_cond_signal(&m_evtCond);
   6563     pthread_mutex_unlock(&m_evtLock);
   6564 }
   6565 
   6566 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
   6567 {
   6568     int32_t rc = NO_ERROR;
   6569     cam_dimension_t str_dim,max_dim;
   6570     QCameraChannel *pChannel;
   6571 
   6572     max_dim.width = 0;
   6573     max_dim.height = 0;
   6574 
   6575     for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
   6576         if (m_channels[j] != NULL) {
   6577             pChannel = m_channels[j];
   6578             for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
   6579                 QCameraStream *pStream = pChannel->getStreamByIndex(i);
   6580                 if (pStream != NULL) {
   6581                     if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
   6582                             || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
   6583                         continue;
   6584                     }
   6585                     pStream->getFrameDimension(str_dim);
   6586                     if (str_dim.width > max_dim.width) {
   6587                         max_dim.width = str_dim.width;
   6588                     }
   6589                     if (str_dim.height > max_dim.height) {
   6590                         max_dim.height = str_dim.height;
   6591                     }
   6592                 }
   6593             }
   6594         }
   6595     }
   6596 
   6597     for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
   6598         QCameraStream *pStream = curChannel->getStreamByIndex(i);
   6599         if (pStream != NULL) {
   6600             if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
   6601                     || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
   6602                 continue;
   6603             }
   6604             pStream->getFrameDimension(str_dim);
   6605             if (str_dim.width > max_dim.width) {
   6606                 max_dim.width = str_dim.width;
   6607             }
   6608             if (str_dim.height > max_dim.height) {
   6609                 max_dim.height = str_dim.height;
   6610             }
   6611         }
   6612     }
   6613     rc = mParameters.updateRAW(max_dim);
   6614     return rc;
   6615 }
   6616 /*===========================================================================
   6617  * FUNCTION   : addStreamToChannel
   6618  *
   6619  * DESCRIPTION: add a stream into a channel
   6620  *
   6621  * PARAMETERS :
   6622  *   @pChannel   : ptr to channel obj
   6623  *   @streamType : type of stream to be added
   6624  *   @streamCB   : callback of stream
   6625  *   @userData   : user data ptr to callback
   6626  *
   6627  * RETURN     : int32_t type of status
   6628  *              NO_ERROR  -- success
   6629  *              none-zero failure code
   6630  *==========================================================================*/
   6631 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
   6632                                                       cam_stream_type_t streamType,
   6633                                                       stream_cb_routine streamCB,
   6634                                                       void *userData)
   6635 {
   6636     int32_t rc = NO_ERROR;
   6637 
   6638     if (streamType == CAM_STREAM_TYPE_RAW) {
   6639         prepareRawStream(pChannel);
   6640     }
   6641     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
   6642     if (pStreamInfo == NULL) {
   6643         LOGE("no mem for stream info buf");
   6644         return NO_MEMORY;
   6645     }
   6646     uint8_t minStreamBufNum = getBufNumRequired(streamType);
   6647     bool bDynAllocBuf = false;
   6648     if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
   6649         bDynAllocBuf = true;
   6650     }
   6651 
   6652     cam_padding_info_t padding_info;
   6653     if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
   6654         padding_info =
   6655                 gCamCapability[mCameraId]->analysis_padding_info;
   6656     } else {
   6657         padding_info =
   6658                 gCamCapability[mCameraId]->padding_info;
   6659         if (streamType == CAM_STREAM_TYPE_PREVIEW) {
   6660             padding_info.width_padding = mSurfaceStridePadding;
   6661             padding_info.height_padding = CAM_PAD_TO_2;
   6662         }
   6663         if((!needReprocess())
   6664                 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
   6665                 || (!mParameters.isLLNoiseEnabled())) {
   6666             padding_info.offset_info.offset_x = 0;
   6667             padding_info.offset_info.offset_y = 0;
   6668         }
   6669     }
   6670 
   6671     bool deferAllocation = needDeferred(streamType);
   6672     LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
   6673             deferAllocation, bDynAllocBuf, streamType);
   6674     rc = pChannel->addStream(*this,
   6675             pStreamInfo,
   6676             NULL,
   6677             minStreamBufNum,
   6678             &padding_info,
   6679             streamCB, userData,
   6680             bDynAllocBuf,
   6681             deferAllocation);
   6682 
   6683     if (rc != NO_ERROR) {
   6684         LOGE("add stream type (%d) failed, ret = %d",
   6685                streamType, rc);
   6686         return rc;
   6687     }
   6688 
   6689     return rc;
   6690 }
   6691 
   6692 /*===========================================================================
   6693  * FUNCTION   : addPreviewChannel
   6694  *
   6695  * DESCRIPTION: add a preview channel that contains a preview stream
   6696  *
   6697  * PARAMETERS : none
   6698  *
   6699  * RETURN     : int32_t type of status
   6700  *              NO_ERROR  -- success
   6701  *              none-zero failure code
   6702  *==========================================================================*/
   6703 int32_t QCamera2HardwareInterface::addPreviewChannel()
   6704 {
   6705     int32_t rc = NO_ERROR;
   6706     QCameraChannel *pChannel = NULL;
   6707     char value[PROPERTY_VALUE_MAX];
   6708     bool raw_yuv = false;
   6709 
   6710 
   6711     if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   6712         // if we had preview channel before, delete it first
   6713         delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
   6714         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
   6715     }
   6716 
   6717     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
   6718                                   mCameraHandle->ops);
   6719     if (NULL == pChannel) {
   6720         LOGE("no mem for preview channel");
   6721         return NO_MEMORY;
   6722     }
   6723 
   6724     // preview only channel, don't need bundle attr and cb
   6725     rc = pChannel->init(NULL, NULL, NULL);
   6726     if (rc != NO_ERROR) {
   6727         LOGE("init preview channel failed, ret = %d", rc);
   6728         return rc;
   6729     }
   6730 
   6731     // meta data stream always coexists with preview if applicable
   6732     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   6733                             metadata_stream_cb_routine, this);
   6734     if (rc != NO_ERROR) {
   6735         LOGE("add metadata stream failed, ret = %d", rc);
   6736         return rc;
   6737     }
   6738 
   6739     if (isRdiMode()) {
   6740         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   6741                                 rdi_mode_stream_cb_routine, this);
   6742     } else {
   6743         if (isNoDisplayMode()) {
   6744             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   6745                                     nodisplay_preview_stream_cb_routine, this);
   6746         } else {
   6747             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   6748                                     preview_stream_cb_routine, this);
   6749             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   6750                     synchronous_stream_cb_routine);
   6751         }
   6752     }
   6753 
   6754     if (((mParameters.fdModeInVideo())
   6755             || (mParameters.getDcrf() == true)
   6756             || (mParameters.getRecordingHintValue() != true))
   6757             && (!mParameters.isSecureMode())) {
   6758         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   6759                 NULL, this);
   6760         if (rc != NO_ERROR) {
   6761             LOGE("add Analysis stream failed, ret = %d", rc);
   6762             return rc;
   6763         }
   6764     }
   6765 
   6766     property_get("persist.camera.raw_yuv", value, "0");
   6767     raw_yuv = atoi(value) > 0 ? true : false;
   6768     if ( raw_yuv ) {
   6769         rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
   6770                 preview_raw_stream_cb_routine,this);
   6771         if ( rc != NO_ERROR ) {
   6772             LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
   6773             delete pChannel;
   6774             return rc;
   6775         }
   6776     }
   6777 
   6778     if (rc != NO_ERROR) {
   6779         LOGE("add preview stream failed, ret = %d", rc);
   6780         delete pChannel;
   6781         return rc;
   6782     }
   6783 
   6784     m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
   6785     return rc;
   6786 }
   6787 
   6788 /*===========================================================================
   6789  * FUNCTION   : addVideoChannel
   6790  *
   6791  * DESCRIPTION: add a video channel that contains a video stream
   6792  *
   6793  * PARAMETERS : none
   6794  *
   6795  * RETURN     : int32_t type of status
   6796  *              NO_ERROR  -- success
   6797  *              none-zero failure code
   6798  *==========================================================================*/
   6799 int32_t QCamera2HardwareInterface::addVideoChannel()
   6800 {
   6801     int32_t rc = NO_ERROR;
   6802     QCameraVideoChannel *pChannel = NULL;
   6803 
   6804     if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
   6805         // if we had video channel before, delete it first
   6806         delete m_channels[QCAMERA_CH_TYPE_VIDEO];
   6807         m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
   6808     }
   6809 
   6810     pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
   6811                                        mCameraHandle->ops);
   6812     if (NULL == pChannel) {
   6813         LOGE("no mem for video channel");
   6814         return NO_MEMORY;
   6815     }
   6816 
   6817     if (isLowPowerMode()) {
   6818         mm_camera_channel_attr_t attr;
   6819         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   6820         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   6821         attr.look_back = 0; //wait for future frame for liveshot
   6822         attr.post_frame_skip = mParameters.getZSLBurstInterval();
   6823         attr.water_mark = 1; //hold min buffers possible in Q
   6824         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   6825         rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
   6826     } else {
   6827         // preview only channel, don't need bundle attr and cb
   6828         rc = pChannel->init(NULL, NULL, NULL);
   6829     }
   6830 
   6831     if (rc != 0) {
   6832         LOGE("init video channel failed, ret = %d", rc);
   6833         delete pChannel;
   6834         return rc;
   6835     }
   6836 
   6837     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
   6838                             video_stream_cb_routine, this);
   6839     if (rc != NO_ERROR) {
   6840         LOGE("add video stream failed, ret = %d", rc);
   6841         delete pChannel;
   6842         return rc;
   6843     }
   6844 
   6845     m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
   6846     return rc;
   6847 }
   6848 
   6849 /*===========================================================================
   6850  * FUNCTION   : addSnapshotChannel
   6851  *
   6852  * DESCRIPTION: add a snapshot channel that contains a snapshot stream
   6853  *
   6854  * PARAMETERS : none
   6855  *
   6856  * RETURN     : int32_t type of status
   6857  *              NO_ERROR  -- success
   6858  *              none-zero failure code
   6859  * NOTE       : Add this channel for live snapshot usecase. Regular capture will
   6860  *              use addCaptureChannel.
   6861  *==========================================================================*/
   6862 int32_t QCamera2HardwareInterface::addSnapshotChannel()
   6863 {
   6864     int32_t rc = NO_ERROR;
   6865     QCameraChannel *pChannel = NULL;
   6866 
   6867     if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
   6868         // if we had ZSL channel before, delete it first
   6869         delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   6870         m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
   6871     }
   6872 
   6873     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
   6874                                   mCameraHandle->ops);
   6875     if (NULL == pChannel) {
   6876         LOGE("no mem for snapshot channel");
   6877         return NO_MEMORY;
   6878     }
   6879 
   6880     mm_camera_channel_attr_t attr;
   6881     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   6882     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   6883     attr.look_back = 0; //wait for future frame for liveshot
   6884     attr.post_frame_skip = mParameters.getZSLBurstInterval();
   6885     attr.water_mark = 1; //hold min buffers possible in Q
   6886     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   6887     attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
   6888     rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
   6889     if (rc != NO_ERROR) {
   6890         LOGE("init snapshot channel failed, ret = %d", rc);
   6891         delete pChannel;
   6892         return rc;
   6893     }
   6894 
   6895     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   6896             NULL, NULL);
   6897     if (rc != NO_ERROR) {
   6898         LOGE("add snapshot stream failed, ret = %d", rc);
   6899         delete pChannel;
   6900         return rc;
   6901     }
   6902 
   6903     m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
   6904     return rc;
   6905 }
   6906 
   6907 /*===========================================================================
   6908  * FUNCTION   : addRawChannel
   6909  *
   6910  * DESCRIPTION: add a raw channel that contains a raw image stream
   6911  *
   6912  * PARAMETERS : none
   6913  *
   6914  * RETURN     : int32_t type of status
   6915  *              NO_ERROR  -- success
   6916  *              none-zero failure code
   6917  *==========================================================================*/
   6918 int32_t QCamera2HardwareInterface::addRawChannel()
   6919 {
   6920     int32_t rc = NO_ERROR;
   6921     QCameraChannel *pChannel = NULL;
   6922 
   6923     if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
   6924         // if we had raw channel before, delete it first
   6925         delete m_channels[QCAMERA_CH_TYPE_RAW];
   6926         m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
   6927     }
   6928 
   6929     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
   6930                                   mCameraHandle->ops);
   6931     if (NULL == pChannel) {
   6932         LOGE("no mem for raw channel");
   6933         return NO_MEMORY;
   6934     }
   6935 
   6936     if (mParameters.getofflineRAW()) {
   6937         mm_camera_channel_attr_t attr;
   6938         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   6939         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   6940         attr.look_back = mParameters.getZSLBackLookCount();
   6941         attr.post_frame_skip = mParameters.getZSLBurstInterval();
   6942         attr.water_mark = 1;
   6943         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   6944         rc = pChannel->init(&attr, raw_channel_cb_routine, this);
   6945         if (rc != NO_ERROR) {
   6946             LOGE("init RAW channel failed, ret = %d", rc);
   6947             delete pChannel;
   6948             return rc;
   6949         }
   6950     } else {
   6951         rc = pChannel->init(NULL, NULL, NULL);
   6952         if (rc != NO_ERROR) {
   6953             LOGE("init raw channel failed, ret = %d", rc);
   6954             delete pChannel;
   6955             return rc;
   6956         }
   6957     }
   6958 
   6959     if (!mParameters.isZSLMode()) {
   6960         // meta data stream always coexists with snapshot in regular RAW capture case
   6961         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   6962                 metadata_stream_cb_routine, this);
   6963         if (rc != NO_ERROR) {
   6964             LOGE("add metadata stream failed, ret = %d", rc);
   6965             delete pChannel;
   6966             return rc;
   6967         }
   6968     }
   6969 
   6970     if (mParameters.getofflineRAW()) {
   6971         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   6972                 NULL, this);
   6973     } else {
   6974         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   6975                 raw_stream_cb_routine, this);
   6976     }
   6977     if (rc != NO_ERROR) {
   6978         LOGE("add snapshot stream failed, ret = %d", rc);
   6979         delete pChannel;
   6980         return rc;
   6981     }
   6982     m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
   6983     return rc;
   6984 }
   6985 
   6986 /*===========================================================================
   6987  * FUNCTION   : addZSLChannel
   6988  *
   6989  * DESCRIPTION: add a ZSL channel that contains a preview stream and
   6990  *              a snapshot stream
   6991  *
   6992  * PARAMETERS : none
   6993  *
   6994  * RETURN     : int32_t type of status
   6995  *              NO_ERROR  -- success
   6996  *              none-zero failure code
   6997  *==========================================================================*/
   6998 int32_t QCamera2HardwareInterface::addZSLChannel()
   6999 {
   7000     int32_t rc = NO_ERROR;
   7001     QCameraPicChannel *pChannel = NULL;
   7002     char value[PROPERTY_VALUE_MAX];
   7003     bool raw_yuv = false;
   7004 
   7005     if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
   7006         // if we had ZSL channel before, delete it first
   7007         delete m_channels[QCAMERA_CH_TYPE_ZSL];
   7008         m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
   7009     }
   7010 
   7011     pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
   7012                                      mCameraHandle->ops);
   7013     if (NULL == pChannel) {
   7014         LOGE("no mem for ZSL channel");
   7015         return NO_MEMORY;
   7016     }
   7017 
   7018     // ZSL channel, init with bundle attr and cb
   7019     mm_camera_channel_attr_t attr;
   7020     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7021     if (mParameters.isSceneSelectionEnabled()) {
   7022         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   7023     } else {
   7024         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7025     }
   7026     attr.look_back = mParameters.getZSLBackLookCount();
   7027     attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7028     if (mParameters.isOEMFeatEnabled()) {
   7029         attr.post_frame_skip++;
   7030     }
   7031     attr.water_mark = mParameters.getZSLQueueDepth();
   7032     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7033     attr.user_expected_frame_id =
   7034         mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
   7035 
   7036     //Enabled matched queue
   7037     if (getRelatedCamSyncInfo()->is_frame_sync_enabled) {
   7038         LOGH("Enabling frame sync for dual camera, camera Id: %d",
   7039                  mCameraId);
   7040         attr.enable_frame_sync = 1;
   7041     }
   7042     rc = pChannel->init(&attr,
   7043                         zsl_channel_cb,
   7044                         this);
   7045     if (rc != 0) {
   7046         LOGE("init ZSL channel failed, ret = %d", rc);
   7047         delete pChannel;
   7048         return rc;
   7049     }
   7050 
   7051     // meta data stream always coexists with preview if applicable
   7052     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7053                             metadata_stream_cb_routine, this);
   7054     if (rc != NO_ERROR) {
   7055         LOGE("add metadata stream failed, ret = %d", rc);
   7056         delete pChannel;
   7057         return rc;
   7058     }
   7059 
   7060     if (isNoDisplayMode()) {
   7061         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7062                                 nodisplay_preview_stream_cb_routine, this);
   7063     } else {
   7064         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7065                                 preview_stream_cb_routine, this);
   7066         pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   7067                 synchronous_stream_cb_routine);
   7068     }
   7069     if (rc != NO_ERROR) {
   7070         LOGE("add preview stream failed, ret = %d", rc);
   7071         delete pChannel;
   7072         return rc;
   7073     }
   7074 
   7075     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   7076                             NULL, this);
   7077     if (rc != NO_ERROR) {
   7078         LOGE("add snapshot stream failed, ret = %d", rc);
   7079         delete pChannel;
   7080         return rc;
   7081     }
   7082 
   7083     if (!mParameters.isSecureMode()) {
   7084         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   7085                 NULL, this);
   7086         if (rc != NO_ERROR) {
   7087             LOGE("add Analysis stream failed, ret = %d", rc);
   7088             delete pChannel;
   7089             return rc;
   7090         }
   7091     }
   7092 
   7093     property_get("persist.camera.raw_yuv", value, "0");
   7094     raw_yuv = atoi(value) > 0 ? true : false;
   7095     if (raw_yuv) {
   7096         rc = addStreamToChannel(pChannel,
   7097                                 CAM_STREAM_TYPE_RAW,
   7098                                 NULL,
   7099                                 this);
   7100         if (rc != NO_ERROR) {
   7101             LOGE("add raw stream failed, ret = %d", rc);
   7102             delete pChannel;
   7103             return rc;
   7104         }
   7105     }
   7106 
   7107     m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
   7108     return rc;
   7109 }
   7110 
   7111 /*===========================================================================
   7112  * FUNCTION   : addCaptureChannel
   7113  *
   7114  * DESCRIPTION: add a capture channel that contains a snapshot stream
   7115  *              and a postview stream
   7116  *
   7117  * PARAMETERS : none
   7118  *
   7119  * RETURN     : int32_t type of status
   7120  *              NO_ERROR  -- success
   7121  *              none-zero failure code
   7122  * NOTE       : Add this channel for regular capture usecase.
   7123  *              For Live snapshot usecase, use addSnapshotChannel.
   7124  *==========================================================================*/
   7125 int32_t QCamera2HardwareInterface::addCaptureChannel()
   7126 {
   7127     int32_t rc = NO_ERROR;
   7128     QCameraPicChannel *pChannel = NULL;
   7129     char value[PROPERTY_VALUE_MAX];
   7130     bool raw_yuv = false;
   7131 
   7132     if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
   7133         delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
   7134         m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
   7135     }
   7136 
   7137     pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
   7138                                   mCameraHandle->ops);
   7139     if (NULL == pChannel) {
   7140         LOGE("no mem for capture channel");
   7141         return NO_MEMORY;
   7142     }
   7143 
   7144     // Capture channel, only need snapshot and postview streams start together
   7145     mm_camera_channel_attr_t attr;
   7146     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7147     if ( mLongshotEnabled ) {
   7148         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7149         attr.look_back = mParameters.getZSLBackLookCount();
   7150         attr.water_mark = mParameters.getZSLQueueDepth();
   7151     } else {
   7152         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   7153     }
   7154     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7155 
   7156     rc = pChannel->init(&attr,
   7157                         capture_channel_cb_routine,
   7158                         this);
   7159     if (rc != NO_ERROR) {
   7160         LOGE("init capture channel failed, ret = %d", rc);
   7161         return rc;
   7162     }
   7163 
   7164     // meta data stream always coexists with snapshot in regular capture case
   7165     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7166                             metadata_stream_cb_routine, this);
   7167     if (rc != NO_ERROR) {
   7168         LOGE("add metadata stream failed, ret = %d", rc);
   7169         return rc;
   7170     }
   7171 
   7172     if (!mLongshotEnabled) {
   7173         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
   7174                                 NULL, this);
   7175 
   7176         if (rc != NO_ERROR) {
   7177             LOGE("add postview stream failed, ret = %d", rc);
   7178             return rc;
   7179         }
   7180     } else {
   7181         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7182                                 preview_stream_cb_routine, this);
   7183 
   7184         if (rc != NO_ERROR) {
   7185             LOGE("add preview stream failed, ret = %d", rc);
   7186             return rc;
   7187         }
   7188         pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   7189                 synchronous_stream_cb_routine);
   7190     }
   7191 
   7192     if (!mParameters.getofflineRAW()) {
   7193         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   7194                 NULL, this);
   7195         if (rc != NO_ERROR) {
   7196             LOGE("add snapshot stream failed, ret = %d", rc);
   7197             return rc;
   7198         }
   7199     }
   7200 
   7201     stream_cb_routine stream_cb = NULL;
   7202     property_get("persist.camera.raw_yuv", value, "0");
   7203     raw_yuv = atoi(value) > 0 ? true : false;
   7204 
   7205     if (raw_yuv) {
   7206         stream_cb = snapshot_raw_stream_cb_routine;
   7207     }
   7208 
   7209     if ((raw_yuv) || (mParameters.getofflineRAW())) {
   7210         rc = addStreamToChannel(pChannel,
   7211                 CAM_STREAM_TYPE_RAW, stream_cb, this);
   7212         if (rc != NO_ERROR) {
   7213             LOGE("add raw stream failed, ret = %d", rc);
   7214             return rc;
   7215         }
   7216     }
   7217 
   7218     m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
   7219     return rc;
   7220 }
   7221 
   7222 /*===========================================================================
   7223  * FUNCTION   : addMetaDataChannel
   7224  *
   7225  * DESCRIPTION: add a meta data channel that contains a metadata stream
   7226  *
   7227  * PARAMETERS : none
   7228  *
   7229  * RETURN     : int32_t type of status
   7230  *              NO_ERROR  -- success
   7231  *              none-zero failure code
   7232  *==========================================================================*/
   7233 int32_t QCamera2HardwareInterface::addMetaDataChannel()
   7234 {
   7235     int32_t rc = NO_ERROR;
   7236     QCameraChannel *pChannel = NULL;
   7237 
   7238     if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
   7239         delete m_channels[QCAMERA_CH_TYPE_METADATA];
   7240         m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
   7241     }
   7242 
   7243     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
   7244                                   mCameraHandle->ops);
   7245     if (NULL == pChannel) {
   7246         LOGE("no mem for metadata channel");
   7247         return NO_MEMORY;
   7248     }
   7249 
   7250     rc = pChannel->init(NULL,
   7251                         NULL,
   7252                         NULL);
   7253     if (rc != NO_ERROR) {
   7254         LOGE("init metadata channel failed, ret = %d", rc);
   7255         delete pChannel;
   7256         return rc;
   7257     }
   7258 
   7259     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7260                             metadata_stream_cb_routine, this);
   7261     if (rc != NO_ERROR) {
   7262         LOGE("add metadata stream failed, ret = %d", rc);
   7263         delete pChannel;
   7264         return rc;
   7265     }
   7266 
   7267     m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
   7268     return rc;
   7269 }
   7270 
   7271 /*===========================================================================
   7272  * FUNCTION   : addCallbackChannel
   7273  *
   7274  * DESCRIPTION: add a callback channel that contains a callback stream
   7275  *
   7276  * PARAMETERS : none
   7277  *
   7278  * RETURN     : int32_t type of status
   7279  *              NO_ERROR  -- success
   7280  *              none-zero failure code
   7281  *==========================================================================*/
   7282 int32_t QCamera2HardwareInterface::addCallbackChannel()
   7283 {
   7284     int32_t rc = NO_ERROR;
   7285     QCameraChannel *pChannel = NULL;
   7286 
   7287     if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
   7288         delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
   7289         m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
   7290     }
   7291 
   7292     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
   7293             mCameraHandle->ops);
   7294     if (NULL == pChannel) {
   7295         LOGE("no mem for callback channel");
   7296         return NO_MEMORY;
   7297     }
   7298 
   7299     rc = pChannel->init(NULL, NULL, this);
   7300     if (rc != NO_ERROR) {
   7301         LOGE("init callback channel failed, ret = %d",
   7302                  rc);
   7303         delete pChannel;
   7304         return rc;
   7305     }
   7306 
   7307     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
   7308             callback_stream_cb_routine, this);
   7309     if (rc != NO_ERROR) {
   7310         LOGE("add callback stream failed, ret = %d", rc);
   7311         delete pChannel;
   7312         return rc;
   7313     }
   7314 
   7315     m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
   7316     return rc;
   7317 }
   7318 
   7319 
   7320 /*===========================================================================
   7321  * FUNCTION   : addAnalysisChannel
   7322  *
   7323  * DESCRIPTION: add a analysis channel that contains a analysis stream
   7324  *
   7325  * PARAMETERS : none
   7326  *
   7327  * RETURN     : int32_t type of status
   7328  *              NO_ERROR  -- success
   7329  *              none-zero failure code
   7330  *==========================================================================*/
   7331 int32_t QCamera2HardwareInterface::addAnalysisChannel()
   7332 {
   7333     int32_t rc = NO_ERROR;
   7334     QCameraChannel *pChannel = NULL;
   7335 
   7336     if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
   7337         delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
   7338         m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
   7339     }
   7340 
   7341     pChannel = new QCameraChannel(mCameraHandle->camera_handle,
   7342                                   mCameraHandle->ops);
   7343     if (NULL == pChannel) {
   7344         LOGE("no mem for metadata channel");
   7345         return NO_MEMORY;
   7346     }
   7347 
   7348     rc = pChannel->init(NULL, NULL, this);
   7349     if (rc != NO_ERROR) {
   7350         LOGE("init Analysis channel failed, ret = %d", rc);
   7351         delete pChannel;
   7352         return rc;
   7353     }
   7354 
   7355     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   7356                             NULL, this);
   7357     if (rc != NO_ERROR) {
   7358         LOGE("add Analysis stream failed, ret = %d", rc);
   7359         delete pChannel;
   7360         return rc;
   7361     }
   7362 
   7363     m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
   7364     return rc;
   7365 }
   7366 
   7367 
   7368 /*===========================================================================
   7369  * FUNCTION   : getPPConfig
   7370  *
   7371  * DESCRIPTION: get Post processing configaration data
   7372  *
   7373  * PARAMETERS :
   7374  * @pp config:  pp config structure pointer,
   7375  * @curIndex:  current pp channel index
   7376  * @multipass: Flag if multipass prcessing enabled.
   7377  *
   7378  * RETURN     : int32_t type of status
   7379  *              NO_ERROR  -- success
   7380  *              none-zero failure code
   7381  *==========================================================================*/
   7382 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
   7383         int8_t curIndex, bool multipass)
   7384 {
   7385     int32_t rc = NO_ERROR;
   7386 
   7387     if (multipass) {
   7388         LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
   7389                 mParameters.getReprocCount(), curIndex);
   7390     }
   7391 
   7392     LOGH("Supported pproc feature mask = %x",
   7393             gCamCapability[mCameraId]->qcom_supported_feature_mask);
   7394     uint32_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
   7395     int32_t zoomLevel = mParameters.getParmZoomLevel();
   7396     uint32_t rotation = mParameters.getJpegRotation();
   7397     int32_t effect = mParameters.getEffectValue();
   7398 
   7399     pp_config.cur_reproc_count = curIndex + 1;
   7400     pp_config.total_reproc_count = mParameters.getReprocCount();
   7401 
   7402     switch(curIndex) {
   7403         case 0:
   7404             //Configure feature mask for first pass of reprocessing
   7405             //check if any effects are enabled
   7406             if ((CAM_EFFECT_MODE_OFF != effect) &&
   7407                 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
   7408                 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
   7409                 pp_config.effect = effect;
   7410             }
   7411 
   7412             //check for features that need to be enabled by default like sharpness
   7413             //(if supported by hw).
   7414             if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
   7415                 !mParameters.isOptiZoomEnabled()) {
   7416                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
   7417                 pp_config.sharpness = mParameters.getSharpness();
   7418             }
   7419 
   7420             //check if zoom is enabled
   7421             if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
   7422                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   7423             }
   7424 
   7425             if (mParameters.isWNREnabled() &&
   7426                 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
   7427                 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
   7428                 pp_config.denoise2d.denoise_enable = 1;
   7429                 pp_config.denoise2d.process_plates =
   7430                         mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
   7431             }
   7432 
   7433             if (isCACEnabled()) {
   7434                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
   7435             }
   7436 
   7437             //check if rotation is required
   7438             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
   7439                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
   7440                 if (rotation == 0) {
   7441                     pp_config.rotation = ROTATE_0;
   7442                 } else if (rotation == 90) {
   7443                     pp_config.rotation = ROTATE_90;
   7444                 } else if (rotation == 180) {
   7445                     pp_config.rotation = ROTATE_180;
   7446                 } else if (rotation == 270) {
   7447                     pp_config.rotation = ROTATE_270;
   7448                 }
   7449             }
   7450 
   7451             if (mParameters.isHDREnabled()){
   7452                 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
   7453                 pp_config.hdr_param.hdr_enable = 1;
   7454                 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
   7455                 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
   7456             } else {
   7457                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
   7458                 pp_config.hdr_param.hdr_enable = 0;
   7459             }
   7460 
   7461             //check if scaling is enabled
   7462             if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
   7463                 mParameters.isReprocScaleEnabled() &&
   7464                 mParameters.isUnderReprocScaling()){
   7465                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   7466                 mParameters.getPicSizeFromAPK(
   7467                         pp_config.scale_param.output_width,
   7468                         pp_config.scale_param.output_height);
   7469             }
   7470 
   7471             if(mParameters.isUbiFocusEnabled()) {
   7472                 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
   7473             } else {
   7474                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
   7475             }
   7476 
   7477             if(mParameters.isUbiRefocus()) {
   7478                 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
   7479                 pp_config.misc_buf_param.misc_buffer_index = 0;
   7480             } else {
   7481                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
   7482             }
   7483 
   7484             if(mParameters.isChromaFlashEnabled()) {
   7485                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
   7486                 pp_config.flash_value = CAM_FLASH_ON;
   7487             } else {
   7488                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
   7489             }
   7490 
   7491             if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
   7492                 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
   7493                 pp_config.zoom_level = (uint8_t) zoomLevel;
   7494             } else {
   7495                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
   7496             }
   7497 
   7498             if (mParameters.getofflineRAW()) {
   7499                 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
   7500             }
   7501 
   7502             if (mParameters.isTruePortraitEnabled()) {
   7503                 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
   7504                 pp_config.misc_buf_param.misc_buffer_index = 0;
   7505             } else {
   7506                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
   7507             }
   7508 
   7509             if(mParameters.isStillMoreEnabled()) {
   7510                 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
   7511             } else {
   7512                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
   7513             }
   7514 
   7515             if (mParameters.isOEMFeatEnabled()) {
   7516                 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
   7517             }
   7518 
   7519             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
   7520                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
   7521                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
   7522                 } else {
   7523                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
   7524                 }
   7525             }
   7526 
   7527             if ((multipass) &&
   7528                     (m_postprocessor.getPPChannelCount() > 1)) {
   7529                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
   7530                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
   7531                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
   7532                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
   7533                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   7534             } else {
   7535                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   7536             }
   7537 
   7538             cam_dimension_t thumb_src_dim;
   7539             cam_dimension_t thumb_dst_dim;
   7540             mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
   7541             mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
   7542             if ((thumb_dst_dim.width != thumb_src_dim.width) ||
   7543                     (thumb_dst_dim.height != thumb_src_dim.height)) {
   7544                 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
   7545                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   7546                 }
   7547             }
   7548 
   7549             break;
   7550 
   7551         case 1:
   7552             //Configure feature mask for second pass of reprocessing
   7553             pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
   7554             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
   7555                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
   7556                 if (rotation == 0) {
   7557                     pp_config.rotation = ROTATE_0;
   7558                 } else if (rotation == 90) {
   7559                     pp_config.rotation = ROTATE_90;
   7560                 } else if (rotation == 180) {
   7561                     pp_config.rotation = ROTATE_180;
   7562                 } else if (rotation == 270) {
   7563                     pp_config.rotation = ROTATE_270;
   7564                 }
   7565             }
   7566             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
   7567                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
   7568                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
   7569                 } else {
   7570                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
   7571                 }
   7572             }
   7573             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
   7574             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
   7575             break;
   7576 
   7577     }
   7578     LOGH("pproc feature mask set = %x pass count = %d",
   7579              pp_config.feature_mask, curIndex);
   7580     return rc;
   7581 }
   7582 
   7583 /*===========================================================================
   7584  * FUNCTION   : addReprocChannel
   7585  *
   7586  * DESCRIPTION: add a reprocess channel that will do reprocess on frames
   7587  *              coming from input channel
   7588  *
   7589  * PARAMETERS :
   7590  *   @pInputChannel : ptr to input channel whose frames will be post-processed
   7591  *   @cur_channel_index : Current channel index in multipass
   7592  *
   7593  * RETURN     : Ptr to the newly created channel obj. NULL if failed.
   7594  *==========================================================================*/
   7595 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
   7596         QCameraChannel *pInputChannel, int8_t cur_channel_index)
   7597 {
   7598     int32_t rc = NO_ERROR;
   7599     QCameraReprocessChannel *pChannel = NULL;
   7600     uint32_t burst_cnt = mParameters.getNumOfSnapshots();
   7601 
   7602     if (pInputChannel == NULL) {
   7603         LOGE("input channel obj is NULL");
   7604         return NULL;
   7605     }
   7606 
   7607     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
   7608                                            mCameraHandle->ops);
   7609     if (NULL == pChannel) {
   7610         LOGE("no mem for reprocess channel");
   7611         return NULL;
   7612     }
   7613 
   7614     // Capture channel, only need snapshot and postview streams start together
   7615     mm_camera_channel_attr_t attr;
   7616     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7617     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   7618     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7619     rc = pChannel->init(&attr,
   7620                         postproc_channel_cb_routine,
   7621                         this);
   7622     if (rc != NO_ERROR) {
   7623         LOGE("init reprocess channel failed, ret = %d", rc);
   7624         delete pChannel;
   7625         return NULL;
   7626     }
   7627 
   7628     // pp feature config
   7629     cam_pp_feature_config_t pp_config;
   7630     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
   7631 
   7632     rc = getPPConfig(pp_config, cur_channel_index,
   7633             ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
   7634     if (rc != NO_ERROR){
   7635         LOGE("Error while creating PP config");
   7636         delete pChannel;
   7637         return NULL;
   7638     }
   7639 
   7640     uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
   7641 
   7642     //WNR and HDR happen inline. No extra buffers needed.
   7643     uint32_t temp_feature_mask = pp_config.feature_mask;
   7644     temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
   7645     if (temp_feature_mask && mParameters.isHDREnabled()) {
   7646         minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
   7647     }
   7648 
   7649     if (mParameters.isStillMoreEnabled()) {
   7650         cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
   7651         pp_config.burst_cnt = stillmore_config.burst_count;
   7652         LOGH("Stillmore burst %d", pp_config.burst_cnt);
   7653 
   7654         // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
   7655         // number of capture is already added. In the case of liveshot,
   7656         // stillmore burst is 1. This is to account for the premature decrement
   7657         if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
   7658             minStreamBufNum += 1;
   7659         }
   7660     }
   7661 
   7662     if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
   7663         minStreamBufNum += mParameters.getReprocCount() - 1;
   7664         burst_cnt = mParameters.getReprocCount();
   7665         if (cur_channel_index == 0) {
   7666             pChannel->setReprocCount(2);
   7667         } else {
   7668             pChannel->setReprocCount(1);
   7669         }
   7670     } else {
   7671         pChannel->setReprocCount(1);
   7672     }
   7673 
   7674     // Add non inplace image lib buffers only when ppproc is present,
   7675     // becuase pproc is non inplace and input buffers for img lib
   7676     // are output for pproc and this number of extra buffers is required
   7677     // If pproc is not there, input buffers for imglib are from snapshot stream
   7678     uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
   7679     if (temp_feature_mask && imglib_extra_bufs) {
   7680         // 1 is added because getNumOfExtraBuffersForImageProc returns extra
   7681         // buffers assuming number of capture is already added
   7682         minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
   7683     }
   7684 
   7685     //Mask out features that are already processed in snapshot stream.
   7686     uint32_t snapshot_feature_mask = 0;
   7687     mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
   7688 
   7689     pp_config.feature_mask &= ~snapshot_feature_mask;
   7690     LOGH("Snapshot feature mask: 0x%x, reproc feature mask: 0x%x",
   7691             snapshot_feature_mask, pp_config.feature_mask);
   7692 
   7693     bool offlineReproc = isRegularCapture();
   7694     if (m_postprocessor.mOfflineDataBufs != NULL) {
   7695         offlineReproc = TRUE;
   7696     }
   7697 
   7698     cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
   7699     paddingInfo.offset_info.offset_x = 0;
   7700     paddingInfo.offset_info.offset_y = 0;
   7701     rc = pChannel->addReprocStreamsFromSource(*this,
   7702                                               pp_config,
   7703                                               pInputChannel,
   7704                                               minStreamBufNum,
   7705                                               burst_cnt,
   7706                                               &paddingInfo,
   7707                                               mParameters,
   7708                                               mLongshotEnabled,
   7709                                               offlineReproc);
   7710     if (rc != NO_ERROR) {
   7711         delete pChannel;
   7712         return NULL;
   7713     }
   7714 
   7715     return pChannel;
   7716 }
   7717 
   7718 /*===========================================================================
   7719  * FUNCTION   : addOfflineReprocChannel
   7720  *
   7721  * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
   7722  *              that will do reprocess on frames coming from external images
   7723  *
   7724  * PARAMETERS :
   7725  *   @img_config  : offline reporcess image info
   7726  *   @pp_feature  : pp feature config
   7727  *
   7728  * RETURN     : int32_t type of status
   7729  *              NO_ERROR  -- success
   7730  *              none-zero failure code
   7731  *==========================================================================*/
   7732 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
   7733                                             cam_pp_offline_src_config_t &img_config,
   7734                                             cam_pp_feature_config_t &pp_feature,
   7735                                             stream_cb_routine stream_cb,
   7736                                             void *userdata)
   7737 {
   7738     int32_t rc = NO_ERROR;
   7739     QCameraReprocessChannel *pChannel = NULL;
   7740 
   7741     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
   7742                                            mCameraHandle->ops);
   7743     if (NULL == pChannel) {
   7744         LOGE("no mem for reprocess channel");
   7745         return NULL;
   7746     }
   7747 
   7748     rc = pChannel->init(NULL, NULL, NULL);
   7749     if (rc != NO_ERROR) {
   7750         LOGE("init reprocess channel failed, ret = %d", rc);
   7751         delete pChannel;
   7752         return NULL;
   7753     }
   7754 
   7755     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
   7756     if (pStreamInfo == NULL) {
   7757         LOGE("no mem for stream info buf");
   7758         delete pChannel;
   7759         return NULL;
   7760     }
   7761 
   7762     cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
   7763     memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
   7764     streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
   7765     streamInfoBuf->fmt = img_config.input_fmt;
   7766     streamInfoBuf->dim = img_config.input_dim;
   7767     streamInfoBuf->buf_planes = img_config.input_buf_planes;
   7768     streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
   7769     streamInfoBuf->num_of_burst = img_config.num_of_bufs;
   7770 
   7771     streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
   7772     streamInfoBuf->reprocess_config.offline = img_config;
   7773     streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
   7774 
   7775     rc = pChannel->addStream(*this,
   7776             pStreamInfo, NULL, img_config.num_of_bufs,
   7777             &gCamCapability[mCameraId]->padding_info,
   7778             stream_cb, userdata, false);
   7779 
   7780     if (rc != NO_ERROR) {
   7781         LOGE("add reprocess stream failed, ret = %d", rc);
   7782         delete pChannel;
   7783         return NULL;
   7784     }
   7785 
   7786     return pChannel;
   7787 }
   7788 
   7789 /*===========================================================================
   7790  * FUNCTION   : addChannel
   7791  *
   7792  * DESCRIPTION: add a channel by its type
   7793  *
   7794  * PARAMETERS :
   7795  *   @ch_type : channel type
   7796  *
   7797  * RETURN     : int32_t type of status
   7798  *              NO_ERROR  -- success
   7799  *              none-zero failure code
   7800  *==========================================================================*/
   7801 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
   7802 {
   7803     int32_t rc = UNKNOWN_ERROR;
   7804     switch (ch_type) {
   7805     case QCAMERA_CH_TYPE_ZSL:
   7806         rc = addZSLChannel();
   7807         break;
   7808     case QCAMERA_CH_TYPE_CAPTURE:
   7809         rc = addCaptureChannel();
   7810         break;
   7811     case QCAMERA_CH_TYPE_PREVIEW:
   7812         rc = addPreviewChannel();
   7813         break;
   7814     case QCAMERA_CH_TYPE_VIDEO:
   7815         rc = addVideoChannel();
   7816         break;
   7817     case QCAMERA_CH_TYPE_SNAPSHOT:
   7818         rc = addSnapshotChannel();
   7819         break;
   7820     case QCAMERA_CH_TYPE_RAW:
   7821         rc = addRawChannel();
   7822         break;
   7823     case QCAMERA_CH_TYPE_METADATA:
   7824         rc = addMetaDataChannel();
   7825         break;
   7826     case QCAMERA_CH_TYPE_CALLBACK:
   7827         rc = addCallbackChannel();
   7828         break;
   7829     case QCAMERA_CH_TYPE_ANALYSIS:
   7830         rc = addAnalysisChannel();
   7831         break;
   7832     default:
   7833         break;
   7834     }
   7835     return rc;
   7836 }
   7837 
   7838 /*===========================================================================
   7839  * FUNCTION   : delChannel
   7840  *
   7841  * DESCRIPTION: delete a channel by its type
   7842  *
   7843  * PARAMETERS :
   7844  *   @ch_type : channel type
   7845  *   @destroy : delete context as well
   7846  *
   7847  * RETURN     : int32_t type of status
   7848  *              NO_ERROR  -- success
   7849  *              none-zero failure code
   7850  *==========================================================================*/
   7851 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
   7852                                               bool destroy)
   7853 {
   7854     if (m_channels[ch_type] != NULL) {
   7855         if (destroy) {
   7856             delete m_channels[ch_type];
   7857             m_channels[ch_type] = NULL;
   7858         } else {
   7859             m_channels[ch_type]->deleteChannel();
   7860         }
   7861     }
   7862 
   7863     return NO_ERROR;
   7864 }
   7865 
   7866 /*===========================================================================
   7867  * FUNCTION   : startChannel
   7868  *
   7869  * DESCRIPTION: start a channel by its type
   7870  *
   7871  * PARAMETERS :
   7872  *   @ch_type : channel type
   7873  *
   7874  * RETURN     : int32_t type of status
   7875  *              NO_ERROR  -- success
   7876  *              none-zero failure code
   7877  *==========================================================================*/
   7878 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
   7879 {
   7880     int32_t rc = UNKNOWN_ERROR;
   7881     if (m_channels[ch_type] != NULL) {
   7882         rc = m_channels[ch_type]->start();
   7883     }
   7884     return rc;
   7885 }
   7886 
   7887 /*===========================================================================
   7888  * FUNCTION   : stopChannel
   7889  *
   7890  * DESCRIPTION: stop a channel by its type
   7891  *
   7892  * PARAMETERS :
   7893  *   @ch_type : channel type
   7894  *
   7895  * RETURN     : int32_t type of status
   7896  *              NO_ERROR  -- success
   7897  *              none-zero failure code
   7898  *==========================================================================*/
   7899 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
   7900 {
   7901     int32_t rc = UNKNOWN_ERROR;
   7902     if (m_channels[ch_type] != NULL) {
   7903         rc = m_channels[ch_type]->stop();
   7904     }
   7905 
   7906     return rc;
   7907 }
   7908 
   7909 /*===========================================================================
   7910  * FUNCTION   : preparePreview
   7911  *
   7912  * DESCRIPTION: add channels needed for preview
   7913  *
   7914  * PARAMETERS : none
   7915  *
   7916  * RETURN     : int32_t type of status
   7917  *              NO_ERROR  -- success
   7918  *              none-zero failure code
   7919  *==========================================================================*/
   7920 int32_t QCamera2HardwareInterface::preparePreview()
   7921 {
   7922     ATRACE_CALL();
   7923     int32_t rc = NO_ERROR;
   7924 
   7925     LOGI("E");
   7926     rc = mParameters.setStreamConfigure(false, false, false);
   7927     if (rc != NO_ERROR) {
   7928         LOGE("setStreamConfigure failed %d", rc);
   7929         return rc;
   7930     }
   7931 
   7932     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
   7933         rc = addChannel(QCAMERA_CH_TYPE_ZSL);
   7934         if (rc != NO_ERROR) {
   7935             LOGE("failed!! rc = %d", rc);
   7936             return rc;
   7937         }
   7938 
   7939         if (mParameters.isUBWCEnabled()) {
   7940             cam_format_t fmt;
   7941             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
   7942             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   7943                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
   7944                 if (rc != NO_ERROR) {
   7945                     delChannel(QCAMERA_CH_TYPE_ZSL);
   7946                     LOGE("failed!! rc = %d", rc);
   7947                     return rc;
   7948                 }
   7949             }
   7950         }
   7951 
   7952         if (mParameters.getofflineRAW()) {
   7953             addChannel(QCAMERA_CH_TYPE_RAW);
   7954         }
   7955     } else {
   7956         bool recordingHint = mParameters.getRecordingHintValue();
   7957         if(!isRdiMode() && recordingHint) {
   7958             //stop face detection,longshot,etc if turned ON in Camera mode
   7959 #ifndef VANILLA_HAL
   7960             int32_t arg; //dummy arg
   7961             if (isLongshotEnabled()) {
   7962                 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
   7963             }
   7964             if (mParameters.isFaceDetectionEnabled()
   7965                     && (!mParameters.fdModeInVideo())) {
   7966                 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
   7967             }
   7968             if (mParameters.isHistogramEnabled()) {
   7969                 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
   7970             }
   7971 #endif
   7972             //Don't create snapshot channel for liveshot, if low power mode is set.
   7973             //Use video stream instead.
   7974             if (!isLowPowerMode()) {
   7975                rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   7976                if (rc != NO_ERROR) {
   7977                    return rc;
   7978                }
   7979             }
   7980 
   7981             rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
   7982             if (rc != NO_ERROR) {
   7983                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   7984                 LOGE("failed!! rc = %d", rc);
   7985                 return rc;
   7986             }
   7987         }
   7988 
   7989         rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
   7990         if (!isRdiMode() && (rc != NO_ERROR)) {
   7991             if (recordingHint) {
   7992                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   7993                 delChannel(QCAMERA_CH_TYPE_VIDEO);
   7994             }
   7995         }
   7996 
   7997         if (mParameters.isUBWCEnabled() && !recordingHint) {
   7998             cam_format_t fmt;
   7999             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
   8000             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   8001                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
   8002                 if (rc != NO_ERROR) {
   8003                     delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8004                     if (!isRdiMode()) {
   8005                         delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8006                         delChannel(QCAMERA_CH_TYPE_VIDEO);
   8007                     }
   8008                     LOGE("failed!! rc = %d", rc);
   8009                     return rc;
   8010                 }
   8011             }
   8012         }
   8013 
   8014         if (NO_ERROR != rc) {
   8015             delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8016             LOGE("failed!! rc = %d", rc);
   8017         }
   8018     }
   8019 
   8020     LOGI("E rc = %d", rc);
   8021     return rc;
   8022 }
   8023 
   8024 /*===========================================================================
   8025  * FUNCTION   : unpreparePreview
   8026  *
   8027  * DESCRIPTION: delete channels for preview
   8028  *
   8029  * PARAMETERS : none
   8030  *
   8031  * RETURN     : none
   8032  *==========================================================================*/
   8033 void QCamera2HardwareInterface::unpreparePreview()
   8034 {
   8035     delChannel(QCAMERA_CH_TYPE_ZSL);
   8036     delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8037     delChannel(QCAMERA_CH_TYPE_VIDEO);
   8038     delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8039     delChannel(QCAMERA_CH_TYPE_CALLBACK);
   8040     delChannel(QCAMERA_CH_TYPE_RAW);
   8041 }
   8042 
   8043 /*===========================================================================
   8044  * FUNCTION   : playShutter
   8045  *
   8046  * DESCRIPTION: send request to play shutter sound
   8047  *
   8048  * PARAMETERS : none
   8049  *
   8050  * RETURN     : none
   8051  *==========================================================================*/
   8052 void QCamera2HardwareInterface::playShutter(){
   8053      if (mNotifyCb == NULL ||
   8054          msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
   8055          LOGD("shutter msg not enabled or NULL cb");
   8056          return;
   8057      }
   8058      LOGH("CAMERA_MSG_SHUTTER ");
   8059      qcamera_callback_argm_t cbArg;
   8060      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   8061      cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
   8062      cbArg.msg_type = CAMERA_MSG_SHUTTER;
   8063      cbArg.ext1 = 0;
   8064      cbArg.ext2 = false;
   8065      m_cbNotifier.notifyCallback(cbArg);
   8066 }
   8067 
   8068 /*===========================================================================
   8069  * FUNCTION   : getChannelByHandle
   8070  *
   8071  * DESCRIPTION: return a channel by its handle
   8072  *
   8073  * PARAMETERS :
   8074  *   @channelHandle : channel handle
   8075  *
   8076  * RETURN     : a channel obj if found, NULL if not found
   8077  *==========================================================================*/
   8078 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
   8079 {
   8080     for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   8081         if (m_channels[i] != NULL &&
   8082             m_channels[i]->getMyHandle() == channelHandle) {
   8083             return m_channels[i];
   8084         }
   8085     }
   8086 
   8087     return NULL;
   8088 }
   8089 /*===========================================================================
   8090  * FUNCTION   : needPreviewFDCallback
   8091  *
   8092  * DESCRIPTION: decides if needPreviewFDCallback
   8093  *
   8094  * PARAMETERS :
   8095  *   @num_faces : number of faces
   8096  *
   8097  * RETURN     : bool type of status
   8098  *              true  -- success
   8099  *              fale -- failure code
   8100  *==========================================================================*/
   8101 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
   8102 {
   8103     if (num_faces == 0 && mNumPreviewFaces == 0) {
   8104         return false;
   8105     }
   8106 
   8107     return true;
   8108 }
   8109 
   8110 /*===========================================================================
   8111  * FUNCTION   : processFaceDetectionReuslt
   8112  *
   8113  * DESCRIPTION: process face detection reuslt
   8114  *
   8115  * PARAMETERS :
   8116  *   @faces_data : ptr to face processing result struct
   8117  *
   8118  * RETURN     : int32_t type of status
   8119  *              NO_ERROR  -- success
   8120  *              none-zero failure code
   8121  *==========================================================================*/
   8122 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
   8123 {
   8124     if (!mParameters.isFaceDetectionEnabled()) {
   8125         LOGH("FaceDetection not enabled, no ops here");
   8126         return NO_ERROR;
   8127     }
   8128 
   8129     qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
   8130     cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
   8131     if ((NULL == mDataCb) ||
   8132         (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
   8133         (!needPreviewFDCallback(detect_data->num_faces_detected))
   8134 #ifndef VANILLA_HAL
   8135         || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
   8136 #endif
   8137         ) {
   8138         LOGH("metadata msgtype not enabled, no ops here");
   8139         return NO_ERROR;
   8140     }
   8141 
   8142     if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
   8143         // Don't send callback to app if this is skipped by fd at backend
   8144         return NO_ERROR;
   8145     }
   8146 
   8147     cam_dimension_t display_dim;
   8148     mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
   8149     if (display_dim.width <= 0 || display_dim.height <= 0) {
   8150         LOGE("Invalid preview width or height (%d x %d)",
   8151                display_dim.width, display_dim.height);
   8152         return UNKNOWN_ERROR;
   8153     }
   8154 
   8155     // process face detection result
   8156     // need separate face detection in preview or snapshot type
   8157     size_t faceResultSize = 0;
   8158     size_t data_len = 0;
   8159     if(fd_type == QCAMERA_FD_PREVIEW){
   8160         //fd for preview frames
   8161         faceResultSize = sizeof(camera_frame_metadata_t);
   8162         faceResultSize += sizeof(camera_face_t) * MAX_ROI;
   8163     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
   8164 #ifndef VANILLA_HAL
   8165         // fd for snapshot frames
   8166         //check if face is detected in this frame
   8167         if(detect_data->num_faces_detected > 0){
   8168             data_len = sizeof(camera_frame_metadata_t) +
   8169                     sizeof(camera_face_t) * detect_data->num_faces_detected;
   8170         }else{
   8171             //no face
   8172             data_len = 0;
   8173         }
   8174 #endif
   8175         faceResultSize = 1 *sizeof(int)    //meta data type
   8176                        + 1 *sizeof(int)    // meta data len
   8177                        + data_len;         //data
   8178     }
   8179 
   8180     camera_memory_t *faceResultBuffer = mGetMemory(-1,
   8181                                                    faceResultSize,
   8182                                                    1,
   8183                                                    mCallbackCookie);
   8184     if ( NULL == faceResultBuffer ) {
   8185         LOGE("Not enough memory for face result data");
   8186         return NO_MEMORY;
   8187     }
   8188 
   8189     unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
   8190     memset(pFaceResult, 0, faceResultSize);
   8191     unsigned char *faceData = NULL;
   8192     if(fd_type == QCAMERA_FD_PREVIEW){
   8193         faceData = pFaceResult;
   8194         mNumPreviewFaces = detect_data->num_faces_detected;
   8195     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
   8196 #ifndef VANILLA_HAL
   8197         //need fill meta type and meta data len first
   8198         int *data_header = (int* )pFaceResult;
   8199         data_header[0] = CAMERA_META_DATA_FD;
   8200         data_header[1] = (int)data_len;
   8201 
   8202         if(data_len <= 0){
   8203             //if face is not valid or do not have face, return
   8204             qcamera_callback_argm_t cbArg;
   8205             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   8206             cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   8207             cbArg.msg_type = CAMERA_MSG_META_DATA;
   8208             cbArg.data = faceResultBuffer;
   8209             cbArg.user_data = faceResultBuffer;
   8210             cbArg.cookie = this;
   8211             cbArg.release_cb = releaseCameraMemory;
   8212             int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   8213             if (rc != NO_ERROR) {
   8214                 LOGE("fail sending notification");
   8215                 faceResultBuffer->release(faceResultBuffer);
   8216             }
   8217             return rc;
   8218         }
   8219 #endif
   8220         faceData = pFaceResult + 2 *sizeof(int); //skip two int length
   8221     }
   8222 
   8223     camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
   8224     camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
   8225 
   8226     roiData->number_of_faces = detect_data->num_faces_detected;
   8227     roiData->faces = faces;
   8228     if (roiData->number_of_faces > 0) {
   8229         for (int i = 0; i < roiData->number_of_faces; i++) {
   8230             faces[i].id = detect_data->faces[i].face_id;
   8231             faces[i].score = detect_data->faces[i].score;
   8232 
   8233             // left
   8234             faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
   8235                     detect_data->faces[i].face_boundary.left,
   8236                     display_dim.width, 2000, -1000);
   8237 
   8238             // top
   8239             faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
   8240                     detect_data->faces[i].face_boundary.top,
   8241                     display_dim.height, 2000, -1000);
   8242 
   8243             // right
   8244             faces[i].rect[2] = faces[i].rect[0] +
   8245                     MAP_TO_DRIVER_COORDINATE(
   8246                     detect_data->faces[i].face_boundary.width,
   8247                     display_dim.width, 2000, 0);
   8248 
   8249              // bottom
   8250             faces[i].rect[3] = faces[i].rect[1] +
   8251                     MAP_TO_DRIVER_COORDINATE(
   8252                     detect_data->faces[i].face_boundary.height,
   8253                     display_dim.height, 2000, 0);
   8254 
   8255             if (faces_data->landmark_valid) {
   8256                 // Center of left eye
   8257                 faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
   8258                         faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
   8259                         display_dim.width, 2000, -1000);
   8260                 faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
   8261                         faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
   8262                         display_dim.height, 2000, -1000);
   8263 
   8264                 // Center of right eye
   8265                 faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
   8266                         faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
   8267                         display_dim.width, 2000, -1000);
   8268                 faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
   8269                         faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
   8270                         display_dim.height, 2000, -1000);
   8271 
   8272                 // Center of mouth
   8273                 faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
   8274                         faces_data->landmark_data.face_landmarks[i].mouth_center.x,
   8275                         display_dim.width, 2000, -1000);
   8276                 faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
   8277                         faces_data->landmark_data.face_landmarks[i].mouth_center.y,
   8278                         display_dim.height, 2000, -1000);
   8279             } else {
   8280                 // return -2000 if invalid
   8281                 faces[i].left_eye[0] = -2000;
   8282                 faces[i].left_eye[1] = -2000;
   8283 
   8284                 faces[i].right_eye[0] = -2000;
   8285                 faces[i].right_eye[1] = -2000;
   8286 
   8287                 faces[i].mouth[0] = -2000;
   8288                 faces[i].mouth[1] = -2000;
   8289             }
   8290 
   8291 #ifndef VANILLA_HAL
   8292 #ifdef TARGET_TS_MAKEUP
   8293             mFaceRect.left = detect_data->faces[i].face_boundary.left;
   8294             mFaceRect.top = detect_data->faces[i].face_boundary.top;
   8295             mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
   8296             mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
   8297 #endif
   8298             if (faces_data->smile_valid) {
   8299                 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
   8300                 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
   8301             }
   8302             if (faces_data->blink_valid) {
   8303                 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
   8304                 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
   8305                 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
   8306             }
   8307             if (faces_data->recog_valid) {
   8308                 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
   8309             }
   8310             if (faces_data->gaze_valid) {
   8311                 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
   8312                 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
   8313                 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
   8314                 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
   8315                 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
   8316                 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
   8317             }
   8318 #endif
   8319 
   8320         }
   8321     }
   8322     else{
   8323 #ifdef TARGET_TS_MAKEUP
   8324         memset(&mFaceRect,-1,sizeof(mFaceRect));
   8325 #endif
   8326     }
   8327     qcamera_callback_argm_t cbArg;
   8328     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   8329     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   8330     if(fd_type == QCAMERA_FD_PREVIEW){
   8331         cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
   8332     }
   8333 #ifndef VANILLA_HAL
   8334     else if(fd_type == QCAMERA_FD_SNAPSHOT){
   8335         cbArg.msg_type = CAMERA_MSG_META_DATA;
   8336     }
   8337 #endif
   8338     cbArg.data = faceResultBuffer;
   8339     cbArg.metadata = roiData;
   8340     cbArg.user_data = faceResultBuffer;
   8341     cbArg.cookie = this;
   8342     cbArg.release_cb = releaseCameraMemory;
   8343     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   8344     if (rc != NO_ERROR) {
   8345         LOGE("fail sending notification");
   8346         faceResultBuffer->release(faceResultBuffer);
   8347     }
   8348 
   8349     return rc;
   8350 }
   8351 
   8352 /*===========================================================================
   8353  * FUNCTION   : releaseCameraMemory
   8354  *
   8355  * DESCRIPTION: releases camera memory objects
   8356  *
   8357  * PARAMETERS :
   8358  *   @data    : buffer to be released
   8359  *   @cookie  : context data
   8360  *   @cbStatus: callback status
   8361  *
   8362  * RETURN     : None
   8363  *==========================================================================*/
   8364 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
   8365                                                     void */*cookie*/,
   8366                                                     int32_t /*cbStatus*/)
   8367 {
   8368     camera_memory_t *mem = ( camera_memory_t * ) data;
   8369     if ( NULL != mem ) {
   8370         mem->release(mem);
   8371     }
   8372 }
   8373 
   8374 /*===========================================================================
   8375  * FUNCTION   : returnStreamBuffer
   8376  *
   8377  * DESCRIPTION: returns back a stream buffer
   8378  *
   8379  * PARAMETERS :
   8380  *   @data    : buffer to be released
   8381  *   @cookie  : context data
   8382  *   @cbStatus: callback status
   8383  *
   8384  * RETURN     : None
   8385  *==========================================================================*/
   8386 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
   8387                                                    void *cookie,
   8388                                                    int32_t /*cbStatus*/)
   8389 {
   8390     QCameraStream *stream = ( QCameraStream * ) cookie;
   8391     int idx = *((int *)data);
   8392     if ((NULL != stream) && (0 <= idx)) {
   8393         stream->bufDone((uint32_t)idx);
   8394     } else {
   8395         LOGE("Cannot return buffer %d %p", idx, cookie);
   8396     }
   8397 }
   8398 
   8399 /*===========================================================================
   8400  * FUNCTION   : processHistogramStats
   8401  *
   8402  * DESCRIPTION: process histogram stats
   8403  *
   8404  * PARAMETERS :
   8405  *   @hist_data : ptr to histogram stats struct
   8406  *
   8407  * RETURN     : int32_t type of status
   8408  *              NO_ERROR  -- success
   8409  *              none-zero failure code
   8410  *==========================================================================*/
   8411 int32_t QCamera2HardwareInterface::processHistogramStats(
   8412         __unused cam_hist_stats_t &stats_data)
   8413 {
   8414 #ifndef VANILLA_HAL
   8415     if (!mParameters.isHistogramEnabled()) {
   8416         LOGH("Histogram not enabled, no ops here");
   8417         return NO_ERROR;
   8418     }
   8419 
   8420     camera_memory_t *histBuffer = mGetMemory(-1,
   8421                                              sizeof(cam_histogram_data_t),
   8422                                              1,
   8423                                              mCallbackCookie);
   8424     if ( NULL == histBuffer ) {
   8425         LOGE("Not enough memory for histogram data");
   8426         return NO_MEMORY;
   8427     }
   8428 
   8429     cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
   8430     if (pHistData == NULL) {
   8431         LOGE("memory data ptr is NULL");
   8432         return UNKNOWN_ERROR;
   8433     }
   8434 
   8435     switch (stats_data.type) {
   8436     case CAM_HISTOGRAM_TYPE_BAYER:
   8437         *pHistData = stats_data.bayer_stats.gb_stats;
   8438         break;
   8439     case CAM_HISTOGRAM_TYPE_YUV:
   8440         *pHistData = stats_data.yuv_stats;
   8441         break;
   8442     }
   8443 
   8444     qcamera_callback_argm_t cbArg;
   8445     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   8446     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   8447     cbArg.msg_type = CAMERA_MSG_STATS_DATA;
   8448     cbArg.data = histBuffer;
   8449     cbArg.user_data = histBuffer;
   8450     cbArg.cookie = this;
   8451     cbArg.release_cb = releaseCameraMemory;
   8452     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   8453     if (rc != NO_ERROR) {
   8454         LOGE("fail sending notification");
   8455         histBuffer->release(histBuffer);
   8456     }
   8457 #endif
   8458     return NO_ERROR;
   8459 }
   8460 
   8461 /*===========================================================================
   8462  * FUNCTION   : calcThermalLevel
   8463  *
   8464  * DESCRIPTION: Calculates the target fps range depending on
   8465  *              the thermal level.
   8466  *              Note that this function can be called from QCameraParametersIntf
   8467  *              while mutex is held. So it should not call back into
   8468  *              QCameraParametersIntf causing deadlock.
   8469  *
   8470  * PARAMETERS :
   8471  *   @level      : received thermal level
   8472  *   @minFPS     : minimum configured fps range
   8473  *   @maxFPS     : maximum configured fps range
   8474  *   @minVideoFps: minimum configured fps range
   8475  *   @maxVideoFps: maximum configured fps range
   8476  *   @adjustedRange : target fps range
   8477  *   @skipPattern : target skip pattern
   8478  *
   8479  * RETURN     : int32_t type of status
   8480  *              NO_ERROR  -- success
   8481  *              none-zero failure code
   8482  *==========================================================================*/
   8483 int QCamera2HardwareInterface::calcThermalLevel(
   8484             qcamera_thermal_level_enum_t level,
   8485             const int minFPSi,
   8486             const int maxFPSi,
   8487             const float &minVideoFps,
   8488             const float &maxVideoFps,
   8489             cam_fps_range_t &adjustedRange,
   8490             enum msm_vfe_frame_skip_pattern &skipPattern)
   8491 {
   8492     const float minFPS = (float)minFPSi;
   8493     const float maxFPS = (float)maxFPSi;
   8494 
   8495     LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
   8496               "video minfps %f, video maxfpS %f",
   8497              level, minFPS, maxFPS, minVideoFps, maxVideoFps);
   8498 
   8499     switch(level) {
   8500     case QCAMERA_THERMAL_NO_ADJUSTMENT:
   8501         {
   8502             adjustedRange.min_fps = minFPS / 1000.0f;
   8503             adjustedRange.max_fps = maxFPS / 1000.0f;
   8504             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   8505             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   8506             skipPattern = NO_SKIP;
   8507         }
   8508         break;
   8509     case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
   8510         {
   8511             adjustedRange.min_fps = minFPS / 1000.0f;
   8512             adjustedRange.max_fps = maxFPS / 1000.0f;
   8513             adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
   8514             adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
   8515             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   8516             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   8517             adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
   8518             adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
   8519             if ( adjustedRange.min_fps < 1 ) {
   8520                 adjustedRange.min_fps = 1;
   8521             }
   8522             if ( adjustedRange.max_fps < 1 ) {
   8523                 adjustedRange.max_fps = 1;
   8524             }
   8525             if ( adjustedRange.video_min_fps < 1 ) {
   8526                 adjustedRange.video_min_fps = 1;
   8527             }
   8528             if ( adjustedRange.video_max_fps < 1 ) {
   8529                 adjustedRange.video_max_fps = 1;
   8530             }
   8531             skipPattern = EVERY_2FRAME;
   8532         }
   8533         break;
   8534     case QCAMERA_THERMAL_BIG_ADJUSTMENT:
   8535         {
   8536             adjustedRange.min_fps = minFPS / 1000.0f;
   8537             adjustedRange.max_fps = maxFPS / 1000.0f;
   8538             adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
   8539             adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
   8540             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   8541             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   8542             adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
   8543             adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
   8544             if ( adjustedRange.min_fps < 1 ) {
   8545                 adjustedRange.min_fps = 1;
   8546             }
   8547             if ( adjustedRange.max_fps < 1 ) {
   8548                 adjustedRange.max_fps = 1;
   8549             }
   8550             if ( adjustedRange.video_min_fps < 1 ) {
   8551                 adjustedRange.video_min_fps = 1;
   8552             }
   8553             if ( adjustedRange.video_max_fps < 1 ) {
   8554                 adjustedRange.video_max_fps = 1;
   8555             }
   8556             skipPattern = EVERY_4FRAME;
   8557         }
   8558         break;
   8559     case QCAMERA_THERMAL_MAX_ADJUSTMENT:
   8560         {
   8561             // Stop Preview?
   8562             // Set lowest min FPS for now
   8563             adjustedRange.min_fps = minFPS/1000.0f;
   8564             adjustedRange.max_fps = minFPS/1000.0f;
   8565             cam_capability_t *capability = gCamCapability[mCameraId];
   8566             for (size_t i = 0;
   8567                      i < capability->fps_ranges_tbl_cnt;
   8568                      i++) {
   8569                 if (capability->fps_ranges_tbl[i].min_fps <
   8570                         adjustedRange.min_fps) {
   8571                     adjustedRange.min_fps =
   8572                             capability->fps_ranges_tbl[i].min_fps;
   8573                     adjustedRange.max_fps = adjustedRange.min_fps;
   8574                 }
   8575             }
   8576             skipPattern = MAX_SKIP;
   8577             adjustedRange.video_min_fps = adjustedRange.min_fps;
   8578             adjustedRange.video_max_fps = adjustedRange.max_fps;
   8579         }
   8580         break;
   8581     case QCAMERA_THERMAL_SHUTDOWN:
   8582         {
   8583             // send error notify
   8584             LOGE("Received shutdown thermal level. Closing camera");
   8585             sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
   8586         }
   8587         break;
   8588     default:
   8589         {
   8590             LOGW("Invalid thermal level %d", level);
   8591             return BAD_VALUE;
   8592         }
   8593         break;
   8594     }
   8595 
   8596     return NO_ERROR;
   8597 }
   8598 
   8599 /*===========================================================================
   8600  * FUNCTION   : recalcFPSRange
   8601  *
   8602  * DESCRIPTION: adjust the configured fps range regarding
   8603  *              the last thermal level.
   8604  *
   8605  * PARAMETERS :
   8606  *   @minFPS      : minimum configured fps range
   8607  *   @maxFPS      : maximum configured fps range
   8608  *   @minVideoFPS : minimum configured video fps
   8609  *   @maxVideoFPS : maximum configured video fps
   8610  *   @adjustedRange : target fps range
   8611  *
   8612  * RETURN     : int32_t type of status
   8613  *              NO_ERROR  -- success
   8614  *              none-zero failure code
   8615  *==========================================================================*/
   8616 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
   8617         const float &minVideoFPS, const float &maxVideoFPS,
   8618         cam_fps_range_t &adjustedRange)
   8619 {
   8620     enum msm_vfe_frame_skip_pattern skipPattern;
   8621     calcThermalLevel(mThermalLevel,
   8622                      minFPS,
   8623                      maxFPS,
   8624                      minVideoFPS,
   8625                      maxVideoFPS,
   8626                      adjustedRange,
   8627                      skipPattern);
   8628     return NO_ERROR;
   8629 }
   8630 
   8631 /*===========================================================================
   8632  * FUNCTION   : updateThermalLevel
   8633  *
   8634  * DESCRIPTION: update thermal level depending on thermal events
   8635  *
   8636  * PARAMETERS :
   8637  *   @level   : thermal level
   8638  *
   8639  * RETURN     : int32_t type of status
   8640  *              NO_ERROR  -- success
   8641  *              none-zero failure code
   8642  *==========================================================================*/
   8643 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
   8644 {
   8645     int ret = NO_ERROR;
   8646     cam_fps_range_t adjustedRange;
   8647     int minFPS, maxFPS;
   8648     float minVideoFPS, maxVideoFPS;
   8649     enum msm_vfe_frame_skip_pattern skipPattern;
   8650     qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
   8651 
   8652 
   8653     if (!mCameraOpened) {
   8654         LOGH("Camera is not opened, no need to update camera parameters");
   8655         return NO_ERROR;
   8656     }
   8657     if (mParameters.getRecordingHintValue()) {
   8658         LOGH("Thermal mitigation isn't enabled in camcorder mode");
   8659         return NO_ERROR;
   8660     }
   8661 
   8662     mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   8663     qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
   8664     if (mParameters.isHfrMode()) {
   8665         cam_fps_range_t hfrFpsRange;
   8666         mParameters.getHfrFps(hfrFpsRange);
   8667         minVideoFPS = hfrFpsRange.video_min_fps;
   8668         maxVideoFPS = hfrFpsRange.video_max_fps;
   8669     } else {
   8670         minVideoFPS = minFPS;
   8671         maxVideoFPS = maxFPS;
   8672     }
   8673 
   8674     calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
   8675             adjustedRange, skipPattern);
   8676     mThermalLevel = level;
   8677 
   8678     if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
   8679         ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
   8680     else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
   8681         ret = mParameters.setFrameSkip(skipPattern);
   8682     else
   8683         LOGW("Incorrect thermal mode %d", thermalMode);
   8684 
   8685     return ret;
   8686 
   8687 }
   8688 
   8689 /*===========================================================================
   8690  * FUNCTION   : updateParameters
   8691  *
   8692  * DESCRIPTION: update parameters
   8693  *
   8694  * PARAMETERS :
   8695  *   @parms       : input parameters string
   8696  *   @needRestart : output, flag to indicate if preview restart is needed
   8697  *
   8698  * RETURN     : int32_t type of status
   8699  *              NO_ERROR  -- success
   8700  *              none-zero failure code
   8701  *==========================================================================*/
   8702 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
   8703 {
   8704     int rc = NO_ERROR;
   8705 
   8706     String8 str = String8(parms);
   8707     rc =  mParameters.updateParameters(str, needRestart);
   8708     setNeedRestart(needRestart);
   8709 
   8710     // update stream based parameter settings
   8711     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   8712         if (m_channels[i] != NULL) {
   8713             m_channels[i]->UpdateStreamBasedParameters(mParameters);
   8714         }
   8715     }
   8716 
   8717     return rc;
   8718 }
   8719 
   8720 /*===========================================================================
   8721  * FUNCTION   : commitParameterChanges
   8722  *
   8723  * DESCRIPTION: commit parameter changes to the backend to take effect
   8724  *
   8725  * PARAMETERS : none
   8726  *
   8727  * RETURN     : int32_t type of status
   8728  *              NO_ERROR  -- success
   8729  *              none-zero failure code
   8730  * NOTE       : This function must be called after updateParameters.
   8731  *              Otherwise, no change will be passed to backend to take effect.
   8732  *==========================================================================*/
   8733 int QCamera2HardwareInterface::commitParameterChanges()
   8734 {
   8735     int rc = NO_ERROR;
   8736     rc = mParameters.commitParameters();
   8737     if (rc == NO_ERROR) {
   8738         // update number of snapshot based on committed parameters setting
   8739         rc = mParameters.setNumOfSnapshot();
   8740     }
   8741     return rc;
   8742 }
   8743 
   8744 /*===========================================================================
   8745  * FUNCTION   : needDebugFps
   8746  *
   8747  * DESCRIPTION: if fps log info need to be printed out
   8748  *
   8749  * PARAMETERS : none
   8750  *
   8751  * RETURN     : true: need print out fps log
   8752  *              false: no need to print out fps log
   8753  *==========================================================================*/
   8754 bool QCamera2HardwareInterface::needDebugFps()
   8755 {
   8756     bool needFps = false;
   8757     needFps = mParameters.isFpsDebugEnabled();
   8758     return needFps;
   8759 }
   8760 
   8761 /*===========================================================================
   8762  * FUNCTION   : isCACEnabled
   8763  *
   8764  * DESCRIPTION: if CAC is enabled
   8765  *
   8766  * PARAMETERS : none
   8767  *
   8768  * RETURN     : true: needed
   8769  *              false: no need
   8770  *==========================================================================*/
   8771 bool QCamera2HardwareInterface::isCACEnabled()
   8772 {
   8773     char prop[PROPERTY_VALUE_MAX];
   8774     memset(prop, 0, sizeof(prop));
   8775     property_get("persist.camera.feature.cac", prop, "0");
   8776     int enableCAC = atoi(prop);
   8777     return enableCAC == 1;
   8778 }
   8779 
   8780 /*===========================================================================
   8781  * FUNCTION   : is4k2kResolution
   8782  *
   8783  * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
   8784  *
   8785  * PARAMETERS : none
   8786  *
   8787  * RETURN     : true: needed
   8788  *              false: no need
   8789  *==========================================================================*/
   8790 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
   8791 {
   8792    bool enabled = false;
   8793    if ((resolution->width == 4096 && resolution->height == 2160) ||
   8794        (resolution->width == 3840 && resolution->height == 2160) ) {
   8795       enabled = true;
   8796    }
   8797    return enabled;
   8798 }
   8799 
   8800 /*===========================================================================
   8801  * FUNCTION   : isPreviewRestartEnabled
   8802  *
   8803  * DESCRIPTION: Check whether preview should be restarted automatically
   8804  *              during image capture.
   8805  *
   8806  * PARAMETERS : none
   8807  *
   8808  * RETURN     : true: needed
   8809  *              false: no need
   8810  *==========================================================================*/
   8811 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
   8812 {
   8813     char prop[PROPERTY_VALUE_MAX];
   8814     memset(prop, 0, sizeof(prop));
   8815     property_get("persist.camera.feature.restart", prop, "0");
   8816     int earlyRestart = atoi(prop);
   8817     return earlyRestart == 1;
   8818 }
   8819 
   8820 /*===========================================================================
   8821  * FUNCTION   : needReprocess
   8822  *
   8823  * DESCRIPTION: if reprocess is needed
   8824  *
   8825  * PARAMETERS : none
   8826  *
   8827  * RETURN     : true: needed
   8828  *              false: no need
   8829  *==========================================================================*/
   8830 bool QCamera2HardwareInterface::needReprocess()
   8831 {
   8832     bool needReprocess = false;
   8833 
   8834     if (!mParameters.isJpegPictureFormat() &&
   8835         !mParameters.isNV21PictureFormat()) {
   8836         // RAW image, no need to reprocess
   8837         return false;
   8838     }
   8839 
   8840     //Disable reprocess for 4K liveshot case but enable if lowpower mode
   8841     if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
   8842             && !isLowPowerMode()) {
   8843         return false;
   8844     }
   8845 
   8846     // pp feature config
   8847     cam_pp_feature_config_t pp_config;
   8848     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
   8849 
   8850     //Decide whether to do reprocess or not based on
   8851     //ppconfig obtained in the first pass.
   8852     getPPConfig(pp_config);
   8853 
   8854     if (pp_config.feature_mask > 0) {
   8855         needReprocess = true;
   8856     }
   8857 
   8858     LOGH("needReprocess %s", needReprocess ? "true" : "false");
   8859     return needReprocess;
   8860 }
   8861 
   8862 
   8863 /*===========================================================================
   8864  * FUNCTION   : needRotationReprocess
   8865  *
   8866  * DESCRIPTION: if rotation needs to be done by reprocess in pp
   8867  *
   8868  * PARAMETERS : none
   8869  *
   8870  * RETURN     : true: needed
   8871  *              false: no need
   8872  *==========================================================================*/
   8873 bool QCamera2HardwareInterface::needRotationReprocess()
   8874 {
   8875     if (!mParameters.isJpegPictureFormat() &&
   8876         !mParameters.isNV21PictureFormat()) {
   8877         // RAW image, no need to reprocess
   8878         return false;
   8879     }
   8880 
   8881     //Disable reprocess for 4K liveshot case
   8882     if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
   8883             && !isLowPowerMode()) {
   8884         //Disable reprocess for 4K liveshot case
   8885         return false;
   8886     }
   8887 
   8888     if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
   8889             CAM_QCOM_FEATURE_ROTATION) > 0 &&
   8890             (mParameters.getJpegRotation() > 0)) {
   8891         // current rotation is not zero, and pp has the capability to process rotation
   8892         LOGH("need to do reprocess for rotation=%d",
   8893                  mParameters.getJpegRotation());
   8894         return true;
   8895     }
   8896 
   8897     return false;
   8898 }
   8899 
   8900 /*===========================================================================
   8901  * FUNCTION   : getThumbnailSize
   8902  *
   8903  * DESCRIPTION: get user set thumbnail size
   8904  *
   8905  * PARAMETERS :
   8906  *   @dim     : output of thumbnail dimension
   8907  *
   8908  * RETURN     : none
   8909  *==========================================================================*/
   8910 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
   8911 {
   8912     mParameters.getThumbnailSize(&dim.width, &dim.height);
   8913 }
   8914 
   8915 /*===========================================================================
   8916  * FUNCTION   : getJpegQuality
   8917  *
   8918  * DESCRIPTION: get user set jpeg quality
   8919  *
   8920  * PARAMETERS : none
   8921  *
   8922  * RETURN     : jpeg quality setting
   8923  *==========================================================================*/
   8924 uint32_t QCamera2HardwareInterface::getJpegQuality()
   8925 {
   8926     uint32_t quality = 0;
   8927     quality =  mParameters.getJpegQuality();
   8928     return quality;
   8929 }
   8930 
   8931 /*===========================================================================
   8932  * FUNCTION   : getExifData
   8933  *
   8934  * DESCRIPTION: get exif data to be passed into jpeg encoding
   8935  *
   8936  * PARAMETERS : none
   8937  *
   8938  * RETURN     : exif data from user setting and GPS
   8939  *==========================================================================*/
   8940 QCameraExif *QCamera2HardwareInterface::getExifData()
   8941 {
   8942     QCameraExif *exif = new QCameraExif();
   8943     if (exif == NULL) {
   8944         LOGE("No memory for QCameraExif");
   8945         return NULL;
   8946     }
   8947 
   8948     int32_t rc = NO_ERROR;
   8949 
   8950     // add exif entries
   8951     String8 dateTime, subSecTime;
   8952     rc = mParameters.getExifDateTime(dateTime, subSecTime);
   8953     if(rc == NO_ERROR) {
   8954         exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
   8955                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   8956         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
   8957                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   8958         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
   8959                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   8960         exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
   8961                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   8962         exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
   8963                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   8964         exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
   8965                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   8966     } else {
   8967         LOGW("getExifDateTime failed");
   8968     }
   8969 
   8970     rat_t focalLength;
   8971     rc = mParameters.getExifFocalLength(&focalLength);
   8972     if (rc == NO_ERROR) {
   8973         exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
   8974                        EXIF_RATIONAL,
   8975                        1,
   8976                        (void *)&(focalLength));
   8977     } else {
   8978         LOGW("getExifFocalLength failed");
   8979     }
   8980 
   8981     uint16_t isoSpeed = mParameters.getExifIsoSpeed();
   8982     if (getSensorType() != CAM_SENSOR_YUV) {
   8983         exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
   8984                        EXIF_SHORT,
   8985                        1,
   8986                        (void *)&(isoSpeed));
   8987     }
   8988 
   8989     char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
   8990     uint32_t count = 0;
   8991 
   8992     /*gps data might not be available */
   8993     rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
   8994     if(rc == NO_ERROR) {
   8995         exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
   8996                        EXIF_ASCII,
   8997                        count,
   8998                        (void *)gpsProcessingMethod);
   8999     } else {
   9000         LOGW("getExifGpsProcessingMethod failed");
   9001     }
   9002 
   9003     rat_t latitude[3];
   9004     char latRef[2];
   9005     rc = mParameters.getExifLatitude(latitude, latRef);
   9006     if(rc == NO_ERROR) {
   9007         exif->addEntry(EXIFTAGID_GPS_LATITUDE,
   9008                        EXIF_RATIONAL,
   9009                        3,
   9010                        (void *)latitude);
   9011         exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
   9012                        EXIF_ASCII,
   9013                        2,
   9014                        (void *)latRef);
   9015     } else {
   9016         LOGW("getExifLatitude failed");
   9017     }
   9018 
   9019     rat_t longitude[3];
   9020     char lonRef[2];
   9021     rc = mParameters.getExifLongitude(longitude, lonRef);
   9022     if(rc == NO_ERROR) {
   9023         exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
   9024                        EXIF_RATIONAL,
   9025                        3,
   9026                        (void *)longitude);
   9027 
   9028         exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
   9029                        EXIF_ASCII,
   9030                        2,
   9031                        (void *)lonRef);
   9032     } else {
   9033         LOGW("getExifLongitude failed");
   9034     }
   9035 
   9036     rat_t altitude;
   9037     char altRef;
   9038     rc = mParameters.getExifAltitude(&altitude, &altRef);
   9039     if(rc == NO_ERROR) {
   9040         exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
   9041                        EXIF_RATIONAL,
   9042                        1,
   9043                        (void *)&(altitude));
   9044 
   9045         exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
   9046                        EXIF_BYTE,
   9047                        1,
   9048                        (void *)&altRef);
   9049     } else {
   9050         LOGW("getExifAltitude failed");
   9051     }
   9052 
   9053     char gpsDateStamp[20];
   9054     rat_t gpsTimeStamp[3];
   9055     rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
   9056     if(rc == NO_ERROR) {
   9057         exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
   9058                        EXIF_ASCII,
   9059                        (uint32_t)(strlen(gpsDateStamp) + 1),
   9060                        (void *)gpsDateStamp);
   9061 
   9062         exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
   9063                        EXIF_RATIONAL,
   9064                        3,
   9065                        (void *)gpsTimeStamp);
   9066     } else {
   9067         LOGW("getExifGpsDataTimeStamp failed");
   9068     }
   9069 
   9070 #ifdef ENABLE_MODEL_INFO_EXIF
   9071 
   9072     char value[PROPERTY_VALUE_MAX];
   9073     if (property_get("persist.sys.exif.make", value, "") > 0 ||
   9074             property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
   9075         exif->addEntry(EXIFTAGID_MAKE,
   9076                 EXIF_ASCII, strlen(value) + 1, (void *)value);
   9077     } else {
   9078         LOGW("getExifMaker failed");
   9079     }
   9080 
   9081     if (property_get("persist.sys.exif.model", value, "") > 0 ||
   9082             property_get("ro.product.model", value, "QCAM-AA") > 0) {
   9083         exif->addEntry(EXIFTAGID_MODEL,
   9084                 EXIF_ASCII, strlen(value) + 1, (void *)value);
   9085     } else {
   9086         LOGW("getExifModel failed");
   9087     }
   9088 
   9089     if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
   9090         exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
   9091                 (uint32_t)(strlen(value) + 1), (void *)value);
   9092     } else {
   9093         LOGW("getExifSoftware failed");
   9094     }
   9095 
   9096 #endif
   9097 
   9098     if (mParameters.useJpegExifRotation()) {
   9099         int16_t orientation;
   9100         switch (mParameters.getJpegExifRotation()) {
   9101         case 0:
   9102             orientation = 1;
   9103             break;
   9104         case 90:
   9105             orientation = 6;
   9106             break;
   9107         case 180:
   9108             orientation = 3;
   9109             break;
   9110         case 270:
   9111             orientation = 8;
   9112             break;
   9113         default:
   9114             orientation = 1;
   9115             break;
   9116         }
   9117         exif->addEntry(EXIFTAGID_ORIENTATION,
   9118                 EXIF_SHORT,
   9119                 1,
   9120                 (void *)&orientation);
   9121         exif->addEntry(EXIFTAGID_TN_ORIENTATION,
   9122                 EXIF_SHORT,
   9123                 1,
   9124                 (void *)&orientation);
   9125     }
   9126 
   9127     return exif;
   9128 }
   9129 
   9130 /*===========================================================================
   9131  * FUNCTION   : setHistogram
   9132  *
   9133  * DESCRIPTION: set if histogram should be enabled
   9134  *
   9135  * PARAMETERS :
   9136  *   @histogram_en : bool flag if histogram should be enabled
   9137  *
   9138  * RETURN     : int32_t type of status
   9139  *              NO_ERROR  -- success
   9140  *              none-zero failure code
   9141  *==========================================================================*/
   9142 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
   9143 {
   9144     return mParameters.setHistogram(histogram_en);
   9145 }
   9146 
   9147 /*===========================================================================
   9148  * FUNCTION   : setFaceDetection
   9149  *
   9150  * DESCRIPTION: set if face detection should be enabled
   9151  *
   9152  * PARAMETERS :
   9153  *   @enabled : bool flag if face detection should be enabled
   9154  *
   9155  * RETURN     : int32_t type of status
   9156  *              NO_ERROR  -- success
   9157  *              none-zero failure code
   9158  *==========================================================================*/
   9159 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
   9160 {
   9161     return mParameters.setFaceDetection(enabled, true);
   9162 }
   9163 
   9164 /*===========================================================================
   9165  * FUNCTION   : isCaptureShutterEnabled
   9166  *
   9167  * DESCRIPTION: Check whether shutter should be triggered immediately after
   9168  *              capture
   9169  *
   9170  * PARAMETERS :
   9171  *
   9172  * RETURN     : true - regular capture
   9173  *              false - other type of capture
   9174  *==========================================================================*/
   9175 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
   9176 {
   9177     char prop[PROPERTY_VALUE_MAX];
   9178     memset(prop, 0, sizeof(prop));
   9179     property_get("persist.camera.feature.shutter", prop, "0");
   9180     int enableShutter = atoi(prop);
   9181     return enableShutter == 1;
   9182 }
   9183 
   9184 /*===========================================================================
   9185  * FUNCTION   : needProcessPreviewFrame
   9186  *
   9187  * DESCRIPTION: returns whether preview frame need to be displayed
   9188  *
   9189  * PARAMETERS :
   9190  *   @frameID : frameID of frame to be processed
   9191  *
   9192  * RETURN     : int32_t type of status
   9193  *              NO_ERROR  -- success
   9194  *              none-zero failure code
   9195  *==========================================================================*/
   9196 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
   9197 {
   9198     return ((m_stateMachine.isPreviewRunning()) &&
   9199             (!isDisplayFrameToSkip(frameID)) &&
   9200             (!mParameters.isInstantAECEnabled()));
   9201 }
   9202 
   9203 /*===========================================================================
   9204  * FUNCTION   : needSendPreviewCallback
   9205  *
   9206  * DESCRIPTION: returns whether preview frame need to callback to APP
   9207  *
   9208  * PARAMETERS :
   9209  *
   9210  * RETURN     : true - need preview frame callbck
   9211  *              false - not send preview frame callback
   9212  *==========================================================================*/
   9213 bool QCamera2HardwareInterface::needSendPreviewCallback()
   9214 {
   9215     return m_stateMachine.isPreviewRunning()
   9216             && (mDataCb != NULL)
   9217             && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
   9218             && m_stateMachine.isPreviewCallbackNeeded();
   9219 };
   9220 
   9221 /*===========================================================================
   9222  * FUNCTION   : setDisplaySkip
   9223  *
   9224  * DESCRIPTION: set range of frames to skip for preview
   9225  *
   9226  * PARAMETERS :
   9227  *   @enabled : TRUE to start skipping frame to display
   9228                 FALSE to stop skipping frame to display
   9229  *   @skipCnt : Number of frame to skip. 0 by default
   9230  *
   9231  * RETURN     : None
   9232  *==========================================================================*/
   9233 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
   9234 {
   9235     pthread_mutex_lock(&mGrallocLock);
   9236     if (enabled) {
   9237         setDisplayFrameSkip();
   9238         setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
   9239     } else {
   9240         setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
   9241     }
   9242     pthread_mutex_unlock(&mGrallocLock);
   9243 }
   9244 
   9245 /*===========================================================================
   9246  * FUNCTION   : setDisplayFrameSkip
   9247  *
   9248  * DESCRIPTION: set range of frames to skip for preview
   9249  *
   9250  * PARAMETERS :
   9251  *   @start   : frameId to start skip
   9252  *   @end     : frameId to stop skip
   9253  *
   9254  * RETURN     : None
   9255  *==========================================================================*/
   9256 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
   9257         uint32_t end)
   9258 {
   9259     if (start == 0) {
   9260         mFrameSkipStart = 0;
   9261         mFrameSkipEnd = 0;
   9262         return;
   9263     }
   9264     if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
   9265         mFrameSkipStart = start;
   9266     }
   9267     if ((end == 0) || (end > mFrameSkipEnd)) {
   9268         mFrameSkipEnd = end;
   9269     }
   9270 }
   9271 
   9272 /*===========================================================================
   9273  * FUNCTION   : isDisplayFrameToSkip
   9274  *
   9275  * DESCRIPTION: function to determin if input frame falls under skip range
   9276  *
   9277  * PARAMETERS :
   9278  *   @frameId : frameId to verify
   9279  *
   9280  * RETURN     : true : need to skip
   9281  *              false: no need to skip
   9282  *==========================================================================*/
   9283 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
   9284 {
   9285     return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
   9286             (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
   9287 }
   9288 
   9289 /*===========================================================================
   9290  * FUNCTION   : prepareHardwareForSnapshot
   9291  *
   9292  * DESCRIPTION: prepare hardware for snapshot, such as LED
   9293  *
   9294  * PARAMETERS :
   9295  *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
   9296  *
   9297  * RETURN     : int32_t type of status
   9298  *              NO_ERROR  -- success
   9299  *              none-zero failure code
   9300  *==========================================================================*/
   9301 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
   9302 {
   9303     ATRACE_CALL();
   9304     LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
   9305     return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
   9306                                                 afNeeded);
   9307 }
   9308 
   9309 /*===========================================================================
   9310  * FUNCTION   : needFDMetadata
   9311  *
   9312  * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
   9313  *
   9314  * PARAMETERS :
   9315  *   @channel_type: channel type
   9316  *
   9317   * RETURN     : true: needed
   9318  *              false: no need
   9319  *==========================================================================*/
   9320 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
   9321 {
   9322     //Note: Currently we only process ZSL channel
   9323     bool value = false;
   9324     if(channel_type == QCAMERA_CH_TYPE_ZSL){
   9325         //check if FD requirement is enabled
   9326         if(mParameters.isSnapshotFDNeeded() &&
   9327            mParameters.isFaceDetectionEnabled()){
   9328             value = true;
   9329             LOGH("Face Detection metadata is required in ZSL mode.");
   9330         }
   9331     }
   9332 
   9333     return value;
   9334 }
   9335 
   9336 /*===========================================================================
   9337  * FUNCTION   : deferredWorkRoutine
   9338  *
   9339  * DESCRIPTION: data process routine that executes deferred tasks
   9340  *
   9341  * PARAMETERS :
   9342  *   @data    : user data ptr (QCamera2HardwareInterface)
   9343  *
   9344  * RETURN     : None
   9345  *==========================================================================*/
   9346 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
   9347 {
   9348     int running = 1;
   9349     int ret;
   9350     uint8_t is_active = FALSE;
   9351     int32_t job_status = 0;
   9352 
   9353     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
   9354     QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
   9355     cmdThread->setName("CAM_defrdWrk");
   9356 
   9357     do {
   9358         do {
   9359             ret = cam_sem_wait(&cmdThread->cmd_sem);
   9360             if (ret != 0 && errno != EINVAL) {
   9361                 LOGE("cam_sem_wait error (%s)",
   9362                          strerror(errno));
   9363                 return NULL;
   9364             }
   9365         } while (ret != 0);
   9366 
   9367         // we got notified about new cmd avail in cmd queue
   9368         camera_cmd_type_t cmd = cmdThread->getCmd();
   9369         LOGD("cmd: %d", cmd);
   9370         switch (cmd) {
   9371         case CAMERA_CMD_TYPE_START_DATA_PROC:
   9372             LOGH("start data proc");
   9373             is_active = TRUE;
   9374             break;
   9375         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
   9376             LOGH("stop data proc");
   9377             is_active = FALSE;
   9378             // signal cmd is completed
   9379             cam_sem_post(&cmdThread->sync_sem);
   9380             break;
   9381         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
   9382             {
   9383                 DefWork *dw =
   9384                     reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
   9385 
   9386                 if ( NULL == dw ) {
   9387                     LOGE("Invalid deferred work");
   9388                     break;
   9389                 }
   9390 
   9391                 switch( dw->cmd ) {
   9392                 case CMD_DEF_ALLOCATE_BUFF:
   9393                     {
   9394                         QCameraChannel * pChannel = dw->args.allocArgs.ch;
   9395 
   9396                         if ( NULL == pChannel ) {
   9397                             LOGE("Invalid deferred work channel");
   9398                             job_status = BAD_VALUE;
   9399                             break;
   9400                         }
   9401 
   9402                         cam_stream_type_t streamType = dw->args.allocArgs.type;
   9403                         LOGH("Deferred buffer allocation started for stream type: %d",
   9404                                  streamType);
   9405 
   9406                         uint32_t iNumOfStreams = pChannel->getNumOfStreams();
   9407                         QCameraStream *pStream = NULL;
   9408                         for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
   9409                             pStream = pChannel->getStreamByIndex(i);
   9410 
   9411                             if ( NULL == pStream ) {
   9412                                 job_status = BAD_VALUE;
   9413                                 break;
   9414                             }
   9415 
   9416                             if ( pStream->isTypeOf(streamType)) {
   9417                                 if ( pStream->allocateBuffers() ) {
   9418                                     LOGE("Error allocating buffers !!!");
   9419                                     job_status =  NO_MEMORY;
   9420                                     pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9421                                             CAMERA_ERROR_UNKNOWN, 0);
   9422                                 }
   9423                                 break;
   9424                             }
   9425                         }
   9426                     }
   9427                     break;
   9428                 case CMD_DEF_PPROC_START:
   9429                     {
   9430                         int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
   9431                         if (ret != NO_ERROR) {
   9432                             job_status = ret;
   9433                             LOGE("PPROC Start failed");
   9434                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9435                                     CAMERA_ERROR_UNKNOWN, 0);
   9436                             break;
   9437                         }
   9438                         QCameraChannel * pChannel = dw->args.pprocArgs;
   9439                         assert(pChannel);
   9440 
   9441                         if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
   9442                             LOGE("cannot start postprocessor");
   9443                             job_status = BAD_VALUE;
   9444                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9445                                     CAMERA_ERROR_UNKNOWN, 0);
   9446                         }
   9447                     }
   9448                     break;
   9449                 case CMD_DEF_METADATA_ALLOC:
   9450                     {
   9451                         int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
   9452                         if (ret != NO_ERROR) {
   9453                             job_status = ret;
   9454                             LOGE("Metadata alloc failed");
   9455                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9456                                     CAMERA_ERROR_UNKNOWN, 0);
   9457                             break;
   9458                         }
   9459                         pme->mMetadataMem = new QCameraMetadataStreamMemory(
   9460                                 QCAMERA_ION_USE_CACHE);
   9461 
   9462                         if (pme->mMetadataMem == NULL) {
   9463                             LOGE("Unable to allocate metadata buffers");
   9464                             job_status = BAD_VALUE;
   9465                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9466                                     CAMERA_ERROR_UNKNOWN, 0);
   9467                         } else {
   9468                             int32_t rc = pme->mMetadataMem->allocate(
   9469                                     dw->args.metadataAllocArgs.bufferCnt,
   9470                                     dw->args.metadataAllocArgs.size,
   9471                                     NON_SECURE);
   9472                             if (rc < 0) {
   9473                                 delete pme->mMetadataMem;
   9474                                 pme->mMetadataMem = NULL;
   9475                             }
   9476                         }
   9477                      }
   9478                      break;
   9479                 case CMD_DEF_CREATE_JPEG_SESSION:
   9480                     {
   9481                         QCameraChannel * pChannel = dw->args.pprocArgs;
   9482                         assert(pChannel);
   9483 
   9484                         int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
   9485                         if (ret != NO_ERROR) {
   9486                             job_status = ret;
   9487                             LOGE("Jpeg create failed");
   9488                             break;
   9489                         }
   9490 
   9491                         if (pme->m_postprocessor.createJpegSession(pChannel)
   9492                             != NO_ERROR) {
   9493                             LOGE("cannot create JPEG session");
   9494                             job_status = UNKNOWN_ERROR;
   9495                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9496                                     CAMERA_ERROR_UNKNOWN, 0);
   9497                         }
   9498                     }
   9499                     break;
   9500                 case CMD_DEF_PPROC_INIT:
   9501                     {
   9502                         int32_t rc = NO_ERROR;
   9503 
   9504                         jpeg_encode_callback_t jpegEvtHandle =
   9505                                 dw->args.pprocInitArgs.jpeg_cb;
   9506                         void* user_data = dw->args.pprocInitArgs.user_data;
   9507                         QCameraPostProcessor *postProcessor =
   9508                                 &(pme->m_postprocessor);
   9509                         uint32_t cameraId = pme->mCameraId;
   9510                         cam_capability_t *capability =
   9511                                 gCamCapability[cameraId];
   9512                         cam_padding_info_t padding_info;
   9513                         cam_padding_info_t& cam_capability_padding_info =
   9514                                 capability->padding_info;
   9515 
   9516                         if(!pme->mJpegClientHandle) {
   9517                             rc = pme->initJpegHandle();
   9518                             if (rc != NO_ERROR) {
   9519                                 LOGE("Error!! creating JPEG handle failed");
   9520                                 job_status = UNKNOWN_ERROR;
   9521                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9522                                         CAMERA_ERROR_UNKNOWN, 0);
   9523                                 break;
   9524                             }
   9525                         }
   9526                         LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
   9527 
   9528                         rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
   9529                                 &pme->mJpegMpoHandle,
   9530                                 pme->mJpegClientHandle);
   9531                         if (rc != 0) {
   9532                             LOGE("Error!! set JPEG handle failed");
   9533                             job_status = UNKNOWN_ERROR;
   9534                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9535                                     CAMERA_ERROR_UNKNOWN, 0);
   9536                             break;
   9537                         }
   9538 
   9539                         /* get max pic size for jpeg work buf calculation*/
   9540                         rc = postProcessor->init(jpegEvtHandle, user_data);
   9541 
   9542                         if (rc != NO_ERROR) {
   9543                             LOGE("cannot init postprocessor");
   9544                             job_status = UNKNOWN_ERROR;
   9545                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9546                                     CAMERA_ERROR_UNKNOWN, 0);
   9547                             break;
   9548                         }
   9549 
   9550                         // update padding info from jpeg
   9551                         postProcessor->getJpegPaddingReq(padding_info);
   9552                         if (cam_capability_padding_info.width_padding <
   9553                                 padding_info.width_padding) {
   9554                             cam_capability_padding_info.width_padding =
   9555                                     padding_info.width_padding;
   9556                         }
   9557                         if (cam_capability_padding_info.height_padding <
   9558                                 padding_info.height_padding) {
   9559                             cam_capability_padding_info.height_padding =
   9560                                     padding_info.height_padding;
   9561                         }
   9562                         if (cam_capability_padding_info.plane_padding !=
   9563                                 padding_info.plane_padding) {
   9564                             cam_capability_padding_info.plane_padding =
   9565                                     mm_stream_calc_lcm(
   9566                                     cam_capability_padding_info.plane_padding,
   9567                                     padding_info.plane_padding);
   9568                         }
   9569                         if (cam_capability_padding_info.offset_info.offset_x
   9570                                 != padding_info.offset_info.offset_x) {
   9571                             cam_capability_padding_info.offset_info.offset_x =
   9572                                     mm_stream_calc_lcm (
   9573                                     cam_capability_padding_info.offset_info.offset_x,
   9574                                     padding_info.offset_info.offset_x);
   9575                         }
   9576                         if (cam_capability_padding_info.offset_info.offset_y
   9577                                 != padding_info.offset_info.offset_y) {
   9578                             cam_capability_padding_info.offset_info.offset_y =
   9579                             mm_stream_calc_lcm (
   9580                                     cam_capability_padding_info.offset_info.offset_y,
   9581                                     padding_info.offset_info.offset_y);
   9582                         }
   9583                     }
   9584                     break;
   9585                 case CMD_DEF_PARAM_ALLOC:
   9586                     {
   9587                         int32_t rc = pme->mParameters.allocate();
   9588                         // notify routine would not be initialized by this time.
   9589                         // So, just update error job status
   9590                         if (rc != NO_ERROR) {
   9591                             job_status = rc;
   9592                             LOGE("Param allocation failed");
   9593                             break;
   9594                         }
   9595                     }
   9596                     break;
   9597                 case CMD_DEF_PARAM_INIT:
   9598                     {
   9599                         int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
   9600                         if (rc != NO_ERROR) {
   9601                             job_status = rc;
   9602                             LOGE("Param init failed");
   9603                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9604                                     CAMERA_ERROR_UNKNOWN, 0);
   9605                             break;
   9606                         }
   9607 
   9608                         uint32_t camId = pme->mCameraId;
   9609                         cam_capability_t * cap = gCamCapability[camId];
   9610 
   9611                         if (pme->mCameraHandle == NULL) {
   9612                             LOGE("Camera handle is null");
   9613                             job_status = BAD_VALUE;
   9614                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9615                                     CAMERA_ERROR_UNKNOWN, 0);
   9616                             break;
   9617                         }
   9618 
   9619                         // Now PostProc need calibration data as initialization
   9620                         // time for jpeg_open and calibration data is a
   9621                         // get param for now, so params needs to be initialized
   9622                         // before postproc init
   9623                         rc = pme->mParameters.init(cap,
   9624                                 pme->mCameraHandle,
   9625                                 pme);
   9626                         if (rc != 0) {
   9627                             job_status = UNKNOWN_ERROR;
   9628                             LOGE("Parameter Initialization failed");
   9629                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9630                                     CAMERA_ERROR_UNKNOWN, 0);
   9631                             break;
   9632                         }
   9633 
   9634                         // Get related cam calibration only in
   9635                         // dual camera mode
   9636                         if (pme->getRelatedCamSyncInfo()->sync_control ==
   9637                                 CAM_SYNC_RELATED_SENSORS_ON) {
   9638                             rc = pme->mParameters.getRelatedCamCalibration(
   9639                                 &(pme->mJpegMetadata.otp_calibration_data));
   9640                             LOGD("Dumping Calibration Data Version Id %f rc %d",
   9641                                     pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
   9642                                     rc);
   9643                             if (rc != 0) {
   9644                                 job_status = UNKNOWN_ERROR;
   9645                                 LOGE("getRelatedCamCalibration failed");
   9646                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9647                                         CAMERA_ERROR_UNKNOWN, 0);
   9648                                 break;
   9649                             }
   9650                             pme->m_bRelCamCalibValid = true;
   9651                         }
   9652 
   9653                         pme->mJpegMetadata.sensor_mount_angle =
   9654                             cap->sensor_mount_angle;
   9655                         pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
   9656 
   9657                         pme->mParameters.setMinPpMask(
   9658                             cap->qcom_supported_feature_mask);
   9659                         pme->mExifParams.debug_params =
   9660                                 (mm_jpeg_debug_exif_params_t *)
   9661                                 malloc(sizeof(mm_jpeg_debug_exif_params_t));
   9662                         if (!pme->mExifParams.debug_params) {
   9663                             LOGE("Out of Memory. Allocation failed for "
   9664                                     "3A debug exif params");
   9665                             job_status = NO_MEMORY;
   9666                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   9667                                     CAMERA_ERROR_UNKNOWN, 0);
   9668                             break;
   9669                         }
   9670                         memset(pme->mExifParams.debug_params, 0,
   9671                                 sizeof(mm_jpeg_debug_exif_params_t));
   9672                     }
   9673                     break;
   9674                 case CMD_DEF_GENERIC:
   9675                     {
   9676                         BackgroundTask *bgTask = dw->args.genericArgs;
   9677                         job_status = bgTask->bgFunction(bgTask->bgArgs);
   9678                     }
   9679                     break;
   9680                 default:
   9681                     LOGE("Incorrect command : %d", dw->cmd);
   9682                 }
   9683 
   9684                 pme->dequeueDeferredWork(dw, job_status);
   9685             }
   9686             break;
   9687         case CAMERA_CMD_TYPE_EXIT:
   9688             running = 0;
   9689             break;
   9690         default:
   9691             break;
   9692         }
   9693     } while (running);
   9694 
   9695     return NULL;
   9696 }
   9697 
   9698 /*===========================================================================
   9699  * FUNCTION   : queueDeferredWork
   9700  *
   9701  * DESCRIPTION: function which queues deferred tasks
   9702  *
   9703  * PARAMETERS :
   9704  *   @cmd     : deferred task
   9705  *   @args    : deferred task arguments
   9706  *
   9707  * RETURN     : job id of deferred job
   9708  *            : 0 in case of error
   9709  *==========================================================================*/
   9710 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
   9711                                                       DeferWorkArgs args)
   9712 {
   9713     Mutex::Autolock l(mDefLock);
   9714     for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
   9715         if (mDefOngoingJobs[i].mDefJobId == 0) {
   9716             DefWork *dw = new DefWork(cmd, sNextJobId, args);
   9717             if (!dw) {
   9718                 LOGE("out of memory.");
   9719                 return 0;
   9720             }
   9721             if (mCmdQueue.enqueue(dw)) {
   9722                 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
   9723                 mDefOngoingJobs[i].mDefJobStatus = 0;
   9724                 if (sNextJobId == 0) { // handle overflow
   9725                     sNextJobId = 1;
   9726                 }
   9727                 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
   9728                         FALSE,
   9729                         FALSE);
   9730                 return mDefOngoingJobs[i].mDefJobId;
   9731             } else {
   9732                 LOGD("Command queue not active! cmd = %d", cmd);
   9733                 delete dw;
   9734                 return 0;
   9735             }
   9736         }
   9737     }
   9738     return 0;
   9739 }
   9740 
   9741 /*===========================================================================
   9742  * FUNCTION   : initJpegHandle
   9743  *
   9744  * DESCRIPTION: Opens JPEG client and gets a handle.
   9745  *                     Sends Dual cam calibration info if present
   9746  *
   9747  * RETURN     : int32_t type of status
   9748  *              NO_ERROR  -- success
   9749  *              none-zero failure code
   9750  *==========================================================================*/
   9751 int32_t QCamera2HardwareInterface::initJpegHandle() {
   9752     // Check if JPEG client handle is present
   9753     LOGH("E");
   9754     if(!mJpegClientHandle) {
   9755         mm_dimension max_size = {0, 0};
   9756         cam_dimension_t size;
   9757 
   9758         mParameters.getMaxPicSize(size);
   9759         max_size.w = size.width;
   9760         max_size.h = size.height;
   9761 
   9762         if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   9763             if (m_bRelCamCalibValid) {
   9764                 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
   9765                         max_size, &mJpegMetadata);
   9766             } else {
   9767                 mJpegClientHandle =  jpeg_open(&mJpegHandle, &mJpegMpoHandle,
   9768                         max_size, NULL);
   9769             }
   9770         } else {
   9771             mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
   9772         }
   9773         if (!mJpegClientHandle) {
   9774             LOGE("Error !! jpeg_open failed!! ");
   9775             return UNKNOWN_ERROR;
   9776         }
   9777         // Set JPEG initialized as true to signify that this camera
   9778         // has initialized the handle
   9779         mJpegHandleOwner = true;
   9780     }
   9781     LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
   9782              mJpegHandleOwner, mJpegClientHandle, mCameraId);
   9783     return NO_ERROR;
   9784 }
   9785 
   9786 /*===========================================================================
   9787  * FUNCTION   : deinitJpegHandle
   9788  *
   9789  * DESCRIPTION: Closes JPEG client using handle
   9790  *
   9791  * RETURN     : int32_t type of status
   9792  *              NO_ERROR  -- success
   9793  *              none-zero failure code
   9794  *==========================================================================*/
   9795 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
   9796     int32_t rc = NO_ERROR;
   9797     LOGH("E");
   9798     // Check if JPEG client handle is present and inited by this camera
   9799     if(mJpegHandleOwner && mJpegClientHandle) {
   9800         rc = mJpegHandle.close(mJpegClientHandle);
   9801         if (rc != NO_ERROR) {
   9802             LOGE("Error!! Closing mJpegClientHandle: %d failed",
   9803                      mJpegClientHandle);
   9804         }
   9805         memset(&mJpegHandle, 0, sizeof(mJpegHandle));
   9806         memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
   9807         mJpegHandleOwner = false;
   9808     }
   9809     mJpegClientHandle = 0;
   9810     LOGH("X rc = %d", rc);
   9811     return rc;
   9812 }
   9813 
   9814 /*===========================================================================
   9815  * FUNCTION   : setJpegHandleInfo
   9816  *
   9817  * DESCRIPTION: sets JPEG client handle info
   9818  *
   9819  * PARAMETERS:
   9820  *                  @ops                    : JPEG ops
   9821  *                  @mpo_ops             : Jpeg MPO ops
   9822  *                  @pJpegClientHandle : o/p Jpeg Client Handle
   9823  *
   9824  * RETURN     : int32_t type of status
   9825  *              NO_ERROR  -- success
   9826  *              none-zero failure code
   9827  *==========================================================================*/
   9828 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
   9829         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
   9830 
   9831     if (pJpegClientHandle && ops && mpo_ops) {
   9832         LOGH("Setting JPEG client handle %d",
   9833                 pJpegClientHandle);
   9834         memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
   9835         memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
   9836         mJpegClientHandle = pJpegClientHandle;
   9837         return NO_ERROR;
   9838     }
   9839     else {
   9840         LOGE("Error!! No Handle found: %d",
   9841                 pJpegClientHandle);
   9842         return BAD_VALUE;
   9843     }
   9844 }
   9845 
   9846 /*===========================================================================
   9847  * FUNCTION   : getJpegHandleInfo
   9848  *
   9849  * DESCRIPTION: gets JPEG client handle info
   9850  *
   9851  * PARAMETERS:
   9852  *                  @ops                    : JPEG ops
   9853  *                  @mpo_ops             : Jpeg MPO ops
   9854  *                  @pJpegClientHandle : o/p Jpeg Client Handle
   9855  *
   9856  * RETURN     : int32_t type of status
   9857  *              NO_ERROR  -- success
   9858  *              none-zero failure code
   9859  *==========================================================================*/
   9860 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
   9861         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
   9862 
   9863     if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   9864         LOGE("Init PProc Deferred work failed");
   9865         return UNKNOWN_ERROR;
   9866     }
   9867     // Copy JPEG ops if present
   9868     if (ops && mpo_ops && pJpegClientHandle) {
   9869         memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
   9870         memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
   9871         *pJpegClientHandle = mJpegClientHandle;
   9872         LOGH("Getting JPEG client handle %d",
   9873                 pJpegClientHandle);
   9874         return NO_ERROR;
   9875     } else {
   9876         return BAD_VALUE;
   9877     }
   9878 }
   9879 
   9880 /*===========================================================================
   9881  * FUNCTION   : dequeueDeferredWork
   9882  *
   9883  * DESCRIPTION: function which dequeues deferred tasks
   9884  *
   9885  * PARAMETERS :
   9886  *   @dw      : deferred work
   9887  *   @jobStatus: deferred task job status
   9888  *
   9889  * RETURN     : int32_t type of status
   9890  *              NO_ERROR  -- success
   9891  *              none-zero failure code
   9892  *==========================================================================*/
   9893 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
   9894 {
   9895     Mutex::Autolock l(mDefLock);
   9896     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   9897         if (mDefOngoingJobs[i].mDefJobId == dw->id) {
   9898             if (jobStatus != NO_ERROR) {
   9899                 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
   9900                 LOGH("updating job status %d for id %d",
   9901                          jobStatus, dw->id);
   9902             } else {
   9903                 mDefOngoingJobs[i].mDefJobId = 0;
   9904                 mDefOngoingJobs[i].mDefJobStatus = 0;
   9905             }
   9906             delete dw;
   9907             mDefCond.broadcast();
   9908             return NO_ERROR;
   9909         }
   9910     }
   9911 
   9912     return UNKNOWN_ERROR;
   9913 }
   9914 
   9915 /*===========================================================================
   9916  * FUNCTION   : getDefJobStatus
   9917  *
   9918  * DESCRIPTION: Gets if a deferred task is success/fail
   9919  *
   9920  * PARAMETERS :
   9921  *   @job_id  : deferred task id
   9922  *
   9923  * RETURN     : NO_ERROR if the job success, otherwise false
   9924  *
   9925  * PRECONDITION : mDefLock is held by current thread
   9926  *==========================================================================*/
   9927 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
   9928 {
   9929     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   9930         if (mDefOngoingJobs[i].mDefJobId == job_id) {
   9931             if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
   9932                 LOGE("job_id (%d) was failed", job_id);
   9933                 return mDefOngoingJobs[i].mDefJobStatus;
   9934             }
   9935             else
   9936                 return NO_ERROR;
   9937         }
   9938     }
   9939     return NO_ERROR;
   9940 }
   9941 
   9942 
   9943 /*===========================================================================
   9944  * FUNCTION   : checkDeferredWork
   9945  *
   9946  * DESCRIPTION: checks if a deferred task is in progress
   9947  *
   9948  * PARAMETERS :
   9949  *   @job_id  : deferred task id
   9950  *
   9951  * RETURN     : true if the task exists, otherwise false
   9952  *
   9953  * PRECONDITION : mDefLock is held by current thread
   9954  *==========================================================================*/
   9955 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
   9956 {
   9957     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   9958         if (mDefOngoingJobs[i].mDefJobId == job_id) {
   9959             return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
   9960         }
   9961     }
   9962     return false;
   9963 }
   9964 
   9965 /*===========================================================================
   9966  * FUNCTION   : waitDeferredWork
   9967  *
   9968  * DESCRIPTION: waits for a deferred task to finish
   9969  *
   9970  * PARAMETERS :
   9971  *   @job_id  : deferred task id
   9972  *
   9973  * RETURN     : int32_t type of status
   9974  *              NO_ERROR  -- success
   9975  *              none-zero failure code
   9976  *==========================================================================*/
   9977 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
   9978 {
   9979     Mutex::Autolock l(mDefLock);
   9980 
   9981     if (job_id == 0) {
   9982         LOGD("Invalid job id %d", job_id);
   9983         return NO_ERROR;
   9984     }
   9985 
   9986     while (checkDeferredWork(job_id) == true ) {
   9987         mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
   9988     }
   9989     return getDefJobStatus(job_id);
   9990 }
   9991 
   9992 /*===========================================================================
   9993  * FUNCTION   : scheduleBackgroundTask
   9994  *
   9995  * DESCRIPTION: Run a requested task in the deferred thread
   9996  *
   9997  * PARAMETERS :
   9998  *   @bgTask  : Task to perform in the background
   9999  *
   10000  * RETURN     : job id of deferred job
   10001  *            : 0 in case of error
   10002  *==========================================================================*/
   10003 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
   10004 {
   10005     DeferWorkArgs args;
   10006     memset(&args, 0, sizeof(DeferWorkArgs));
   10007     args.genericArgs = bgTask;
   10008 
   10009     return queueDeferredWork(CMD_DEF_GENERIC, args);
   10010 }
   10011 
   10012 /*===========================================================================
   10013  * FUNCTION   : waitForBackgroundTask
   10014  *
   10015  * DESCRIPTION: Wait for a background task to complete
   10016  *
   10017  * PARAMETERS :
   10018  *   @taskId  : Task id to wait for
   10019  *
   10020  * RETURN     : int32_t type of status
   10021  *              NO_ERROR  -- success
   10022  *              none-zero failure code
   10023  *==========================================================================*/
   10024 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
   10025 {
   10026     return waitDeferredWork(taskId);
   10027 }
   10028 
   10029 /*===========================================================================
   10030  * FUNCTION   : needDeferedAllocation
   10031  *
   10032  * DESCRIPTION: Function to decide background task for streams
   10033  *
   10034  * PARAMETERS :
   10035  *   @stream_type  : stream type
   10036  *
   10037  * RETURN     : true - if background task is needed
   10038  *              false -  if background task is NOT needed
   10039  *==========================================================================*/
   10040 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
   10041 {
   10042     if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
   10043             || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
   10044         return FALSE;
   10045     }
   10046 
   10047     if ((stream_type == CAM_STREAM_TYPE_RAW)
   10048             && (mParameters.getofflineRAW())) {
   10049         return FALSE;
   10050     }
   10051 
   10052     if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
   10053             && (!mParameters.getRecordingHintValue())){
   10054         return TRUE;
   10055     }
   10056 
   10057     if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
   10058             || (stream_type == CAM_STREAM_TYPE_METADATA)
   10059             || (stream_type == CAM_STREAM_TYPE_RAW)
   10060             || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
   10061         return TRUE;
   10062     }
   10063 
   10064     if (stream_type == CAM_STREAM_TYPE_VIDEO) {
   10065         return FALSE;
   10066     }
   10067     return FALSE;
   10068 }
   10069 
   10070 /*===========================================================================
   10071  * FUNCTION   : isRegularCapture
   10072  *
   10073  * DESCRIPTION: Check configuration for regular catpure
   10074  *
   10075  * PARAMETERS :
   10076  *
   10077  * RETURN     : true - regular capture
   10078  *              false - other type of capture
   10079  *==========================================================================*/
   10080 bool QCamera2HardwareInterface::isRegularCapture()
   10081 {
   10082     bool ret = false;
   10083 
   10084     if (numOfSnapshotsExpected() == 1 &&
   10085         !isLongshotEnabled() &&
   10086         !mParameters.isHDREnabled() &&
   10087         !mParameters.getRecordingHintValue() &&
   10088         !isZSLMode() && !mParameters.getofflineRAW()) {
   10089             ret = true;
   10090     }
   10091     return ret;
   10092 }
   10093 
   10094 /*===========================================================================
   10095  * FUNCTION   : getLogLevel
   10096  *
   10097  * DESCRIPTION: Reads the log level property into a variable
   10098  *
   10099  * PARAMETERS :
   10100  *   None
   10101  *
   10102  * RETURN     :
   10103  *   None
   10104  *==========================================================================*/
   10105 void QCamera2HardwareInterface::getLogLevel()
   10106 {
   10107     char prop[PROPERTY_VALUE_MAX];
   10108 
   10109     property_get("persist.camera.kpi.debug", prop, "1");
   10110     gKpiDebugLevel = atoi(prop);
   10111     return;
   10112 }
   10113 
   10114 /*===========================================================================
   10115  * FUNCTION   : getSensorType
   10116  *
   10117  * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
   10118  *
   10119  * PARAMETERS :
   10120  *   None
   10121  *
   10122  * RETURN     : Type of sensor - bayer or YUV
   10123  *
   10124  *==========================================================================*/
   10125 cam_sensor_t QCamera2HardwareInterface::getSensorType()
   10126 {
   10127     return gCamCapability[mCameraId]->sensor_type.sens_type;
   10128 }
   10129 
   10130 /*===========================================================================
   10131  * FUNCTION   : startRAWChannel
   10132  *
   10133  * DESCRIPTION: start RAW Channel
   10134  *
   10135  * PARAMETERS :
   10136  *   @pChannel  : Src channel to link this RAW channel.
   10137  *
   10138  * RETURN     : int32_t type of status
   10139  *              NO_ERROR  -- success
   10140  *              none-zero failure code
   10141  *==========================================================================*/
   10142 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
   10143 {
   10144     int32_t rc = NO_ERROR;
   10145     QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
   10146     if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
   10147         // Find and try to link a metadata stream from preview channel
   10148         QCameraStream *pMetaStream = NULL;
   10149 
   10150         if (pMetaChannel != NULL) {
   10151             uint32_t streamNum = pMetaChannel->getNumOfStreams();
   10152             QCameraStream *pStream = NULL;
   10153             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   10154                 pStream = pMetaChannel->getStreamByIndex(i);
   10155                 if ((NULL != pStream) &&
   10156                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
   10157                     pMetaStream = pStream;
   10158                     break;
   10159                 }
   10160             }
   10161 
   10162             if (NULL != pMetaStream) {
   10163                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   10164                 if (NO_ERROR != rc) {
   10165                     LOGE("Metadata stream link failed %d", rc);
   10166                 }
   10167             }
   10168         }
   10169         rc = pChannel->start();
   10170     }
   10171     return rc;
   10172 }
   10173 
   10174 /*===========================================================================
   10175  * FUNCTION   : startRecording
   10176  *
   10177  * DESCRIPTION: start recording impl
   10178  *
   10179  * PARAMETERS : none
   10180  *
   10181  * RETURN     : int32_t type of status
   10182  *              NO_ERROR  -- success
   10183  *              none-zero failure code
   10184  *==========================================================================*/
   10185 int32_t QCamera2HardwareInterface::stopRAWChannel()
   10186 {
   10187     int32_t rc = NO_ERROR;
   10188     rc = stopChannel(QCAMERA_CH_TYPE_RAW);
   10189     return rc;
   10190 }
   10191 
   10192 /*===========================================================================
   10193  * FUNCTION   : isLowPowerMode
   10194  *
   10195  * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
   10196  *
   10197  * PARAMETERS :
   10198  *   None
   10199  *
   10200  * RETURN     : TRUE/FALSE
   10201  *
   10202  *==========================================================================*/
   10203 bool QCamera2HardwareInterface::isLowPowerMode()
   10204 {
   10205     cam_dimension_t dim;
   10206     mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
   10207 
   10208     char prop[PROPERTY_VALUE_MAX];
   10209     property_get("camera.lowpower.record.enable", prop, "0");
   10210     int enable = atoi(prop);
   10211 
   10212     //Enable low power mode if :
   10213     //1. Video resolution is 2k (2048x1080) or above and
   10214     //2. camera.lowpower.record.enable is set
   10215 
   10216     bool isLowpower = mParameters.getRecordingHintValue() && enable
   10217             && ((dim.width * dim.height) >= (2048 * 1080));
   10218     return isLowpower;
   10219 }
   10220 
   10221 }; // namespace qcamera
   10222