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