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