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 #define CAMERA_MIN_DISPLAY_BUFFERS       2
     66 #define CAMERA_DEFAULT_FPS               30000
     67 
     68 #define HDR_CONFIDENCE_THRESHOLD 0.4
     69 
     70 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds
     71 
     72 // Very long wait, just to be sure we don't deadlock
     73 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
     74 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
     75 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
     76 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
     77 #define CAMERA_MAX_PARAM_APPLY_DELAY 3
     78 
     79 namespace qcamera {
     80 
     81 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
     82 extern pthread_mutex_t gCamLock;
     83 volatile uint32_t gCamHalLogLevel = 1;
     84 extern uint8_t gNumCameraSessions;
     85 uint32_t QCamera2HardwareInterface::sNextJobId = 1;
     86 
     87 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
     88     .set_preview_window =        QCamera2HardwareInterface::set_preview_window,
     89     .set_callbacks =             QCamera2HardwareInterface::set_CallBacks,
     90     .enable_msg_type =           QCamera2HardwareInterface::enable_msg_type,
     91     .disable_msg_type =          QCamera2HardwareInterface::disable_msg_type,
     92     .msg_type_enabled =          QCamera2HardwareInterface::msg_type_enabled,
     93 
     94     .start_preview =             QCamera2HardwareInterface::start_preview,
     95     .stop_preview =              QCamera2HardwareInterface::stop_preview,
     96     .preview_enabled =           QCamera2HardwareInterface::preview_enabled,
     97     .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,
     98 
     99     .start_recording =           QCamera2HardwareInterface::start_recording,
    100     .stop_recording =            QCamera2HardwareInterface::stop_recording,
    101     .recording_enabled =         QCamera2HardwareInterface::recording_enabled,
    102     .release_recording_frame =   QCamera2HardwareInterface::release_recording_frame,
    103 
    104     .auto_focus =                QCamera2HardwareInterface::auto_focus,
    105     .cancel_auto_focus =         QCamera2HardwareInterface::cancel_auto_focus,
    106 
    107     .take_picture =              QCamera2HardwareInterface::take_picture,
    108     .cancel_picture =            QCamera2HardwareInterface::cancel_picture,
    109 
    110     .set_parameters =            QCamera2HardwareInterface::set_parameters,
    111     .get_parameters =            QCamera2HardwareInterface::get_parameters,
    112     .put_parameters =            QCamera2HardwareInterface::put_parameters,
    113     .send_command =              QCamera2HardwareInterface::send_command,
    114 
    115     .release =                   QCamera2HardwareInterface::release,
    116     .dump =                      QCamera2HardwareInterface::dump,
    117 };
    118 
    119 /*===========================================================================
    120  * FUNCTION   : set_preview_window
    121  *
    122  * DESCRIPTION: set preview window.
    123  *
    124  * PARAMETERS :
    125  *   @device  : ptr to camera device struct
    126  *   @window  : window ops table
    127  *
    128  * RETURN     : int32_t type of status
    129  *              NO_ERROR  -- success
    130  *              none-zero failure code
    131  *==========================================================================*/
    132 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
    133         struct preview_stream_ops *window)
    134 {
    135     ATRACE_CALL();
    136     int rc = NO_ERROR;
    137     QCamera2HardwareInterface *hw =
    138         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    139     if (!hw) {
    140         LOGE("NULL camera device");
    141         return BAD_VALUE;
    142     }
    143     LOGD("E camera id %d window = %p", hw->getCameraId(), window);
    144 
    145     hw->lockAPI();
    146     qcamera_api_result_t apiResult;
    147     rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
    148     if (rc == NO_ERROR) {
    149         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
    150         rc = apiResult.status;
    151     }
    152     hw->unlockAPI();
    153     LOGD("X camera id %d", hw->getCameraId());
    154 
    155     return rc;
    156 }
    157 
    158 /*===========================================================================
    159  * FUNCTION   : set_CallBacks
    160  *
    161  * DESCRIPTION: set callbacks for notify and data
    162  *
    163  * PARAMETERS :
    164  *   @device     : ptr to camera device struct
    165  *   @notify_cb  : notify cb
    166  *   @data_cb    : data cb
    167  *   @data_cb_timestamp  : video data cd with timestamp
    168  *   @get_memory : ops table for request gralloc memory
    169  *   @user       : user data ptr
    170  *
    171  * RETURN     : none
    172  *==========================================================================*/
    173 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
    174         camera_notify_callback notify_cb,
    175         camera_data_callback data_cb,
    176         camera_data_timestamp_callback data_cb_timestamp,
    177         camera_request_memory get_memory,
    178         void *user)
    179 {
    180     ATRACE_CALL();
    181     QCamera2HardwareInterface *hw =
    182         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    183     if (!hw) {
    184         LOGE("NULL camera device");
    185         return;
    186     }
    187     LOGD("E camera id %d", hw->getCameraId());
    188 
    189     qcamera_sm_evt_setcb_payload_t payload;
    190     payload.notify_cb = notify_cb;
    191     payload.data_cb = data_cb;
    192     payload.data_cb_timestamp = data_cb_timestamp;
    193     payload.get_memory = get_memory;
    194     payload.user = user;
    195 
    196     hw->lockAPI();
    197     qcamera_api_result_t apiResult;
    198     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
    199     if (rc == NO_ERROR) {
    200         hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
    201     }
    202     hw->unlockAPI();
    203     LOGD("X camera id %d", hw->getCameraId());
    204 
    205 }
    206 
    207 /*===========================================================================
    208  * FUNCTION   : enable_msg_type
    209  *
    210  * DESCRIPTION: enable certain msg type
    211  *
    212  * PARAMETERS :
    213  *   @device     : ptr to camera device struct
    214  *   @msg_type   : msg type mask
    215  *
    216  * RETURN     : none
    217  *==========================================================================*/
    218 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
    219 {
    220     ATRACE_CALL();
    221     QCamera2HardwareInterface *hw =
    222         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    223     if (!hw) {
    224         LOGE("NULL camera device");
    225         return;
    226     }
    227     LOGD("E camera id %d", hw->getCameraId());
    228 
    229     hw->lockAPI();
    230     qcamera_api_result_t apiResult;
    231     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
    232     if (rc == NO_ERROR) {
    233         hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
    234     }
    235     hw->unlockAPI();
    236     LOGD("X camera id %d", hw->getCameraId());
    237 
    238 }
    239 
    240 /*===========================================================================
    241  * FUNCTION   : disable_msg_type
    242  *
    243  * DESCRIPTION: disable certain msg type
    244  *
    245  * PARAMETERS :
    246  *   @device     : ptr to camera device struct
    247  *   @msg_type   : msg type mask
    248  *
    249  * RETURN     : none
    250  *==========================================================================*/
    251 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
    252 {
    253     ATRACE_CALL();
    254     QCamera2HardwareInterface *hw =
    255         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    256     if (!hw) {
    257         LOGE("NULL camera device");
    258         return;
    259     }
    260     LOGD("E camera id %d", hw->getCameraId());
    261 
    262     hw->lockAPI();
    263     qcamera_api_result_t apiResult;
    264     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
    265     if (rc == NO_ERROR) {
    266         hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
    267     }
    268     hw->unlockAPI();
    269     LOGD("X camera id %d", hw->getCameraId());
    270 
    271 }
    272 
    273 /*===========================================================================
    274  * FUNCTION   : msg_type_enabled
    275  *
    276  * DESCRIPTION: if certain msg type is enabled
    277  *
    278  * PARAMETERS :
    279  *   @device     : ptr to camera device struct
    280  *   @msg_type   : msg type mask
    281  *
    282  * RETURN     : 1 -- enabled
    283  *              0 -- not enabled
    284  *==========================================================================*/
    285 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
    286 {
    287     ATRACE_CALL();
    288     int ret = NO_ERROR;
    289     QCamera2HardwareInterface *hw =
    290         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    291     if (!hw) {
    292         LOGE("NULL camera device");
    293         return BAD_VALUE;
    294     }
    295     LOGD("E camera id %d", hw->getCameraId());
    296 
    297     hw->lockAPI();
    298     qcamera_api_result_t apiResult;
    299     ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
    300     if (ret == NO_ERROR) {
    301         hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
    302         ret = apiResult.enabled;
    303     }
    304     hw->unlockAPI();
    305     LOGD("X camera id %d", hw->getCameraId());
    306 
    307    return ret;
    308 }
    309 
    310 /*===========================================================================
    311  * FUNCTION   : prepare_preview
    312  *
    313  * DESCRIPTION: prepare preview
    314  *
    315  * PARAMETERS :
    316  *   @device  : ptr to camera device struct
    317  *
    318  * RETURN     : int32_t type of status
    319  *              NO_ERROR  -- success
    320  *              none-zero failure code
    321  *==========================================================================*/
    322 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
    323 {
    324     ATRACE_CALL();
    325     int ret = NO_ERROR;
    326     QCamera2HardwareInterface *hw =
    327         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    328     if (!hw) {
    329         LOGE("NULL camera device");
    330         return BAD_VALUE;
    331     }
    332     LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
    333              hw->getCameraId());
    334     hw->lockAPI();
    335     qcamera_api_result_t apiResult;
    336     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
    337     ret = hw->processAPI(evt, NULL);
    338     if (ret == NO_ERROR) {
    339         hw->waitAPIResult(evt, &apiResult);
    340         ret = apiResult.status;
    341     }
    342     hw->unlockAPI();
    343     LOGH("[KPI Perf]: X");
    344     return ret;
    345 }
    346 
    347 
    348 /*===========================================================================
    349  * FUNCTION   : start_preview
    350  *
    351  * DESCRIPTION: start preview
    352  *
    353  * PARAMETERS :
    354  *   @device  : ptr to camera device struct
    355  *
    356  * RETURN     : int32_t type of status
    357  *              NO_ERROR  -- success
    358  *              none-zero failure code
    359  *==========================================================================*/
    360 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
    361 {
    362     KPI_ATRACE_CALL();
    363     int ret = NO_ERROR;
    364     QCamera2HardwareInterface *hw =
    365         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    366     if (!hw) {
    367         LOGE("NULL camera device");
    368         return BAD_VALUE;
    369     }
    370     LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
    371              hw->getCameraId());
    372 
    373     // Release the timed perf lock acquired in openCamera
    374     hw->m_perfLock.lock_rel_timed();
    375 
    376     hw->m_perfLock.lock_acq();
    377     hw->lockAPI();
    378     qcamera_api_result_t apiResult;
    379     qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
    380     if (hw->isNoDisplayMode()) {
    381         evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
    382     }
    383     ret = hw->processAPI(evt, NULL);
    384     if (ret == NO_ERROR) {
    385         hw->waitAPIResult(evt, &apiResult);
    386         ret = apiResult.status;
    387     }
    388     hw->unlockAPI();
    389     hw->m_bPreviewStarted = true;
    390     LOGI("[KPI Perf]: X ret = %d", ret);
    391     return ret;
    392 }
    393 
    394 /*===========================================================================
    395  * FUNCTION   : stop_preview
    396  *
    397  * DESCRIPTION: stop preview
    398  *
    399  * PARAMETERS :
    400  *   @device  : ptr to camera device struct
    401  *
    402  * RETURN     : none
    403  *==========================================================================*/
    404 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
    405 {
    406     KPI_ATRACE_CALL();
    407     QCamera2HardwareInterface *hw =
    408         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    409     if (!hw) {
    410         LOGE("NULL camera device");
    411         return;
    412     }
    413     LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
    414              hw->getCameraId());
    415 
    416     // Disable power Hint for preview
    417     hw->m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
    418 
    419     hw->m_perfLock.lock_acq();
    420     hw->lockAPI();
    421     qcamera_api_result_t apiResult;
    422     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
    423     if (ret == NO_ERROR) {
    424         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult);
    425     }
    426     hw->unlockAPI();
    427     LOGI("[KPI Perf]: X ret = %d", ret);
    428 }
    429 
    430 /*===========================================================================
    431  * FUNCTION   : preview_enabled
    432  *
    433  * DESCRIPTION: if preview is running
    434  *
    435  * PARAMETERS :
    436  *   @device  : ptr to camera device struct
    437  *
    438  * RETURN     : 1 -- running
    439  *              0 -- not running
    440  *==========================================================================*/
    441 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
    442 {
    443     ATRACE_CALL();
    444     int ret = NO_ERROR;
    445     QCamera2HardwareInterface *hw =
    446         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    447     if (!hw) {
    448         LOGE("NULL camera device");
    449         return BAD_VALUE;
    450     }
    451     LOGD("E camera id %d", hw->getCameraId());
    452 
    453     hw->lockAPI();
    454     qcamera_api_result_t apiResult;
    455     ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
    456     if (ret == NO_ERROR) {
    457         hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult);
    458         ret = apiResult.enabled;
    459     }
    460 
    461     //if preview enabled, can enable preview callback send
    462     if(apiResult.enabled) {
    463         hw->m_stateMachine.setPreviewCallbackNeeded(true);
    464     }
    465     hw->unlockAPI();
    466     LOGD("X camera id %d", hw->getCameraId());
    467 
    468     return ret;
    469 }
    470 
    471 /*===========================================================================
    472  * FUNCTION   : store_meta_data_in_buffers
    473  *
    474  * DESCRIPTION: if need to store meta data in buffers for video frame
    475  *
    476  * PARAMETERS :
    477  *   @device  : ptr to camera device struct
    478  *   @enable  : flag if enable
    479  *
    480  * RETURN     : int32_t type of status
    481  *              NO_ERROR  -- success
    482  *              none-zero failure code
    483  *==========================================================================*/
    484 int QCamera2HardwareInterface::store_meta_data_in_buffers(
    485                 struct camera_device *device, int enable)
    486 {
    487     int ret = NO_ERROR;
    488     QCamera2HardwareInterface *hw =
    489         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    490     if (!hw) {
    491         LOGE("NULL camera device");
    492         return BAD_VALUE;
    493     }
    494     LOGD("E camera id %d", hw->getCameraId());
    495 
    496     hw->lockAPI();
    497     qcamera_api_result_t apiResult;
    498     ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable);
    499     if (ret == NO_ERROR) {
    500         hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult);
    501         ret = apiResult.status;
    502     }
    503     hw->unlockAPI();
    504     LOGD("X camera id %d", hw->getCameraId());
    505 
    506     return ret;
    507 }
    508 
    509 /*===========================================================================
    510  * FUNCTION   : restart_start_preview
    511  *
    512  * DESCRIPTION: start preview as part of the restart preview
    513  *
    514  * PARAMETERS :
    515  *   @device  : ptr to camera device struct
    516  *
    517  * RETURN     : int32_t type of status
    518  *              NO_ERROR  -- success
    519  *              none-zero failure code
    520  *==========================================================================*/
    521 int QCamera2HardwareInterface::restart_start_preview(struct camera_device *device)
    522 {
    523     ATRACE_CALL();
    524     int ret = NO_ERROR;
    525     QCamera2HardwareInterface *hw =
    526         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    527     if (!hw) {
    528         LOGE("NULL camera device");
    529         return BAD_VALUE;
    530     }
    531     LOGI("E camera id %d", hw->getCameraId());
    532     hw->lockAPI();
    533     qcamera_api_result_t apiResult;
    534 
    535     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
    536         ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_START_PREVIEW, NULL);
    537         if (ret == NO_ERROR) {
    538             hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_START_PREVIEW, &apiResult);
    539             ret = apiResult.status;
    540         }
    541     } else {
    542         LOGE("This function is not supposed to be called in single-camera mode");
    543         ret = INVALID_OPERATION;
    544     }
    545     // Preview restart done, update the mPreviewRestartNeeded flag to false.
    546     hw->mPreviewRestartNeeded = false;
    547     hw->unlockAPI();
    548     LOGI("X camera id %d", hw->getCameraId());
    549 
    550     return ret;
    551 }
    552 
    553 /*===========================================================================
    554  * FUNCTION   : restart_stop_preview
    555  *
    556  * DESCRIPTION: stop preview as part of the restart preview
    557  *
    558  * PARAMETERS :
    559  *   @device  : ptr to camera device struct
    560  *
    561  * RETURN     : int32_t type of status
    562  *              NO_ERROR  -- success
    563  *              none-zero failure code
    564  *==========================================================================*/
    565 int QCamera2HardwareInterface::restart_stop_preview(struct camera_device *device)
    566 {
    567     ATRACE_CALL();
    568     int ret = NO_ERROR;
    569     QCamera2HardwareInterface *hw =
    570         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    571     if (!hw) {
    572         LOGE("NULL camera device");
    573         return BAD_VALUE;
    574     }
    575     LOGI("E camera id %d", hw->getCameraId());
    576     hw->lockAPI();
    577     qcamera_api_result_t apiResult;
    578 
    579     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
    580         ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, NULL);
    581         if (ret == NO_ERROR) {
    582             hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, &apiResult);
    583             ret = apiResult.status;
    584         }
    585     } else {
    586         LOGE("This function is not supposed to be called in single-camera mode");
    587         ret = INVALID_OPERATION;
    588     }
    589 
    590     hw->unlockAPI();
    591     LOGI("X camera id %d", hw->getCameraId());
    592 
    593     return ret;
    594 }
    595 
    596 /*===========================================================================
    597  * FUNCTION   : pre_start_recording
    598  *
    599  * DESCRIPTION: prepare for the start recording
    600  *
    601  * PARAMETERS :
    602  *   @device  : ptr to camera device struct
    603  *
    604  * RETURN     : int32_t type of status
    605  *              NO_ERROR  -- success
    606  *              none-zero failure code
    607  *==========================================================================*/
    608 int QCamera2HardwareInterface::pre_start_recording(struct camera_device *device)
    609 {
    610     ATRACE_CALL();
    611     int ret = NO_ERROR;
    612     QCamera2HardwareInterface *hw =
    613         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    614     if (!hw) {
    615         LOGE("NULL camera device");
    616         return BAD_VALUE;
    617     }
    618     LOGH("[KPI Perf]: E PROFILE_PRE_START_RECORDING camera id %d",
    619           hw->getCameraId());
    620     hw->lockAPI();
    621     qcamera_api_result_t apiResult;
    622     ret = hw->processAPI(QCAMERA_SM_EVT_PRE_START_RECORDING, NULL);
    623     if (ret == NO_ERROR) {
    624         hw->waitAPIResult(QCAMERA_SM_EVT_PRE_START_RECORDING, &apiResult);
    625         ret = apiResult.status;
    626     }
    627     hw->unlockAPI();
    628     LOGH("[KPI Perf]: X");
    629     return ret;
    630 }
    631 
    632 /*===========================================================================
    633  * FUNCTION   : start_recording
    634  *
    635  * DESCRIPTION: start recording
    636  *
    637  * PARAMETERS :
    638  *   @device  : ptr to camera device struct
    639  *
    640  * RETURN     : int32_t type of status
    641  *              NO_ERROR  -- success
    642  *              none-zero failure code
    643  *==========================================================================*/
    644 int QCamera2HardwareInterface::start_recording(struct camera_device *device)
    645 {
    646     ATRACE_CALL();
    647     int ret = NO_ERROR;
    648     QCamera2HardwareInterface *hw =
    649         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    650     if (!hw) {
    651         LOGE("NULL camera device");
    652         return BAD_VALUE;
    653     }
    654     LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
    655           hw->getCameraId());
    656     // Give HWI control to call pre_start_recording in single camera mode.
    657     // In dual-cam mode, this control belongs to muxer.
    658     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    659         ret = pre_start_recording(device);
    660         if (ret != NO_ERROR) {
    661             LOGE("pre_start_recording failed with ret = %d", ret);
    662             return ret;
    663         }
    664     }
    665 
    666     hw->lockAPI();
    667     qcamera_api_result_t apiResult;
    668     ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
    669     if (ret == NO_ERROR) {
    670         hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
    671         ret = apiResult.status;
    672     }
    673     hw->unlockAPI();
    674     hw->m_bRecordStarted = true;
    675     LOGI("[KPI Perf]: X ret = %d", ret);
    676 
    677     return ret;
    678 }
    679 
    680 /*===========================================================================
    681  * FUNCTION   : stop_recording
    682  *
    683  * DESCRIPTION: stop recording
    684  *
    685  * PARAMETERS :
    686  *   @device  : ptr to camera device struct
    687  *
    688  * RETURN     : none
    689  *==========================================================================*/
    690 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
    691 {
    692     ATRACE_CALL();
    693     QCamera2HardwareInterface *hw =
    694         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    695     if (!hw) {
    696         LOGE("NULL camera device");
    697         return;
    698     }
    699     LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
    700              hw->getCameraId());
    701 
    702     hw->lockAPI();
    703     qcamera_api_result_t apiResult;
    704     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
    705     if (ret == NO_ERROR) {
    706         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
    707     }
    708     hw->unlockAPI();
    709     LOGI("[KPI Perf]: X ret = %d", ret);
    710 }
    711 
    712 /*===========================================================================
    713  * FUNCTION   : recording_enabled
    714  *
    715  * DESCRIPTION: if recording is running
    716  *
    717  * PARAMETERS :
    718  *   @device  : ptr to camera device struct
    719  *
    720  * RETURN     : 1 -- running
    721  *              0 -- not running
    722  *==========================================================================*/
    723 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
    724 {
    725     ATRACE_CALL();
    726     int ret = NO_ERROR;
    727     QCamera2HardwareInterface *hw =
    728         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    729     if (!hw) {
    730         LOGE("NULL camera device");
    731         return BAD_VALUE;
    732     }
    733     LOGD("E camera id %d", hw->getCameraId());
    734     hw->lockAPI();
    735     qcamera_api_result_t apiResult;
    736     ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
    737     if (ret == NO_ERROR) {
    738         hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
    739         ret = apiResult.enabled;
    740     }
    741     hw->unlockAPI();
    742     LOGD("X camera id %d", hw->getCameraId());
    743 
    744     return ret;
    745 }
    746 
    747 /*===========================================================================
    748  * FUNCTION   : release_recording_frame
    749  *
    750  * DESCRIPTION: return recording frame back
    751  *
    752  * PARAMETERS :
    753  *   @device  : ptr to camera device struct
    754  *   @opaque  : ptr to frame to be returned
    755  *
    756  * RETURN     : none
    757  *==========================================================================*/
    758 void QCamera2HardwareInterface::release_recording_frame(
    759             struct camera_device *device, const void *opaque)
    760 {
    761     ATRACE_CALL();
    762     int32_t ret = NO_ERROR;
    763     QCamera2HardwareInterface *hw =
    764         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    765     if (!hw) {
    766         LOGE("NULL camera device");
    767         return;
    768     }
    769     if (!opaque) {
    770         LOGE("Error!! Frame info is NULL");
    771         return;
    772     }
    773     LOGD("E camera id %d", hw->getCameraId());
    774 
    775     hw->lockAPI();
    776     qcamera_api_result_t apiResult;
    777     ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
    778     if (ret == NO_ERROR) {
    779         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
    780     }
    781     hw->unlockAPI();
    782     LOGD("X camera id %d", hw->getCameraId());
    783 }
    784 
    785 /*===========================================================================
    786  * FUNCTION   : auto_focus
    787  *
    788  * DESCRIPTION: start auto focus
    789  *
    790  * PARAMETERS :
    791  *   @device  : ptr to camera device struct
    792  *
    793  * RETURN     : int32_t type of status
    794  *              NO_ERROR  -- success
    795  *              none-zero failure code
    796  *==========================================================================*/
    797 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
    798 {
    799     KPI_ATRACE_INT("Camera:AutoFocus", 1);
    800     int ret = NO_ERROR;
    801     QCamera2HardwareInterface *hw =
    802         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    803     if (!hw) {
    804         LOGE("NULL camera device");
    805         return BAD_VALUE;
    806     }
    807     LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
    808              hw->getCameraId());
    809     hw->lockAPI();
    810     qcamera_api_result_t apiResult;
    811     ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
    812     if (ret == NO_ERROR) {
    813         hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
    814         ret = apiResult.status;
    815     }
    816     hw->unlockAPI();
    817     LOGH("[KPI Perf] : X ret = %d", ret);
    818 
    819     return ret;
    820 }
    821 
    822 /*===========================================================================
    823  * FUNCTION   : cancel_auto_focus
    824  *
    825  * DESCRIPTION: cancel auto focus
    826  *
    827  * PARAMETERS :
    828  *   @device  : ptr to camera device struct
    829  *
    830  * RETURN     : int32_t type of status
    831  *              NO_ERROR  -- success
    832  *              none-zero failure code
    833  *==========================================================================*/
    834 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
    835 {
    836     ATRACE_CALL();
    837     int ret = NO_ERROR;
    838     QCamera2HardwareInterface *hw =
    839         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    840     if (!hw) {
    841         LOGE("NULL camera device");
    842         return BAD_VALUE;
    843     }
    844     LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
    845              hw->getCameraId());
    846     hw->lockAPI();
    847     qcamera_api_result_t apiResult;
    848     ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
    849     if (ret == NO_ERROR) {
    850         hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
    851         ret = apiResult.status;
    852     }
    853     hw->unlockAPI();
    854     LOGH("[KPI Perf] : X ret = %d", ret);
    855     return ret;
    856 }
    857 
    858 /*===========================================================================
    859  * FUNCTION   : pre_take_picture
    860  *
    861  * DESCRIPTION: pre take picture, restart preview if necessary.
    862  *
    863  * PARAMETERS :
    864  *   @device  : ptr to camera device struct
    865  *
    866  * RETURN     : int32_t type of status
    867  *              NO_ERROR  -- success
    868  *              none-zero failure code
    869  *==========================================================================*/
    870 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
    871 {
    872     ATRACE_CALL();
    873     int ret = NO_ERROR;
    874     QCamera2HardwareInterface *hw =
    875         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    876     if (!hw) {
    877         LOGE("NULL camera device");
    878         return BAD_VALUE;
    879     }
    880     LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
    881           hw->getCameraId());
    882     hw->lockAPI();
    883     qcamera_api_result_t apiResult;
    884     ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
    885     if (ret == NO_ERROR) {
    886         hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
    887         ret = apiResult.status;
    888     }
    889     hw->unlockAPI();
    890     LOGH("[KPI Perf]: X");
    891     return ret;
    892 }
    893 
    894 /*===========================================================================
    895  * FUNCTION   : take_picture
    896  *
    897  * DESCRIPTION: take picture
    898  *
    899  * PARAMETERS :
    900  *   @device  : ptr to camera device struct
    901  *
    902  * RETURN     : int32_t type of status
    903  *              NO_ERROR  -- success
    904  *              none-zero failure code
    905  *==========================================================================*/
    906 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
    907 {
    908     KPI_ATRACE_CALL();
    909     int ret = NO_ERROR;
    910     QCamera2HardwareInterface *hw =
    911         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    912     if (!hw) {
    913         LOGE("NULL camera device");
    914         return BAD_VALUE;
    915     }
    916     LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
    917              hw->getCameraId());
    918     if (!hw->mLongshotEnabled) {
    919         hw->m_perfLock.lock_acq();
    920     }
    921     qcamera_api_result_t apiResult;
    922 
    923    /** Added support for Retro-active Frames:
    924      *  takePicture() is called before preparing Snapshot to indicate the
    925      *  mm-camera-channel to pick up legacy frames even
    926      *  before LED estimation is triggered.
    927      */
    928 
    929     LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
    930            hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
    931            hw->isLongshotEnabled());
    932 
    933     // Check for Retro-active Frames
    934     if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
    935         !hw->isLiveSnapshot() && hw->isZSLMode() &&
    936         !hw->isHDRMode() && !hw->isLongshotEnabled()) {
    937         // Set Retro Picture Mode
    938         hw->setRetroPicture(1);
    939         hw->m_bLedAfAecLock = 0;
    940         LOGL("Retro Enabled");
    941 
    942         // Give HWI control to call pre_take_picture in single camera mode.
    943         // In dual-cam mode, this control belongs to muxer.
    944         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    945             ret = pre_take_picture(device);
    946             if (ret != NO_ERROR) {
    947                 LOGE("pre_take_picture failed with ret = %d",ret);
    948                 return ret;
    949             }
    950         }
    951 
    952         /* Call take Picture for total number of snapshots required.
    953              This includes the number of retro frames and normal frames */
    954         hw->lockAPI();
    955         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
    956         if (ret == NO_ERROR) {
    957           // Wait for retro frames, before calling prepare snapshot
    958           LOGD("Wait for Retro frames to be done");
    959           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
    960             ret = apiResult.status;
    961         }
    962         /* Unlock API since it is acquired in prepare snapshot seperately */
    963         hw->unlockAPI();
    964 
    965         /* Prepare snapshot in case LED needs to be flashed */
    966         LOGD("Start Prepare Snapshot");
    967         ret = hw->prepare_snapshot(device);
    968     }
    969     else {
    970         hw->setRetroPicture(0);
    971         // Check if prepare snapshot is done
    972         if (!hw->mPrepSnapRun) {
    973             // Ignore the status from prepare_snapshot
    974             hw->prepare_snapshot(device);
    975         }
    976 
    977         // Give HWI control to call pre_take_picture in single camera mode.
    978         // In dual-cam mode, this control belongs to muxer.
    979         if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
    980             ret = pre_take_picture(device);
    981             if (ret != NO_ERROR) {
    982                 LOGE("pre_take_picture failed with ret = %d",ret);
    983                 return ret;
    984             }
    985         }
    986 
    987         // Regardless what the result value for prepare_snapshot,
    988         // go ahead with capture anyway. Just like the way autofocus
    989         // is handled in capture case
    990         /* capture */
    991         LOGL("Capturing normal frames");
    992         hw->lockAPI();
    993         ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
    994         if (ret == NO_ERROR) {
    995           hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
    996             ret = apiResult.status;
    997         }
    998         hw->unlockAPI();
    999         if (!hw->isLongshotEnabled()){
   1000             // For longshot mode, we prepare snapshot only once
   1001             hw->mPrepSnapRun = false;
   1002          }
   1003     }
   1004     LOGI("[KPI Perf]: X ret = %d", ret);
   1005     return ret;
   1006 }
   1007 
   1008 /*===========================================================================
   1009  * FUNCTION   : cancel_picture
   1010  *
   1011  * DESCRIPTION: cancel current take picture request
   1012  *
   1013  * PARAMETERS :
   1014  *   @device  : ptr to camera device struct
   1015  *
   1016  * RETURN     : int32_t type of status
   1017  *              NO_ERROR  -- success
   1018  *              none-zero failure code
   1019  *==========================================================================*/
   1020 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
   1021 {
   1022     ATRACE_CALL();
   1023     int ret = NO_ERROR;
   1024     QCamera2HardwareInterface *hw =
   1025         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1026     if (!hw) {
   1027         LOGE("NULL camera device");
   1028         return BAD_VALUE;
   1029     }
   1030     LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
   1031              hw->getCameraId());
   1032     hw->lockAPI();
   1033     qcamera_api_result_t apiResult;
   1034     ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
   1035     if (ret == NO_ERROR) {
   1036         hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
   1037         ret = apiResult.status;
   1038     }
   1039     hw->unlockAPI();
   1040     LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);
   1041 
   1042     return ret;
   1043 }
   1044 
   1045 /*===========================================================================
   1046  * FUNCTION   : set_parameters
   1047  *
   1048  * DESCRIPTION: set camera parameters
   1049  *
   1050  * PARAMETERS :
   1051  *   @device  : ptr to camera device struct
   1052  *   @parms   : string of packed parameters
   1053  *
   1054  * RETURN     : int32_t type of status
   1055  *              NO_ERROR  -- success
   1056  *              none-zero failure code
   1057  *==========================================================================*/
   1058 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
   1059                                               const char *parms)
   1060 {
   1061     ATRACE_CALL();
   1062     int ret = NO_ERROR;
   1063     QCamera2HardwareInterface *hw =
   1064         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1065     if (!hw) {
   1066         LOGE("NULL camera device");
   1067         return BAD_VALUE;
   1068     }
   1069     LOGD("E camera id %d", hw->getCameraId());
   1070     hw->lockAPI();
   1071     qcamera_api_result_t apiResult;
   1072     ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
   1073     if (ret == NO_ERROR) {
   1074         hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
   1075         ret = apiResult.status;
   1076     }
   1077 
   1078     // Give HWI control to restart (if necessary) after set params
   1079     // in single camera mode. In dual-cam mode, this control belongs to muxer.
   1080     if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   1081         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
   1082             LOGD("stopping after param change");
   1083             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
   1084             if (ret == NO_ERROR) {
   1085                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
   1086                 ret = apiResult.status;
   1087             }
   1088         }
   1089 
   1090         if (ret == NO_ERROR) {
   1091             LOGD("committing param change");
   1092             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
   1093             if (ret == NO_ERROR) {
   1094                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
   1095                 ret = apiResult.status;
   1096             }
   1097         }
   1098 
   1099         if ((ret == NO_ERROR) && hw->getNeedRestart()) {
   1100             LOGD("restarting after param change");
   1101             ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
   1102             if (ret == NO_ERROR) {
   1103                 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
   1104                 ret = apiResult.status;
   1105             }
   1106         }
   1107     }
   1108 
   1109     hw->unlockAPI();
   1110     LOGD("X camera id %d ret %d", hw->getCameraId(), ret);
   1111 
   1112     return ret;
   1113 }
   1114 
   1115 /*===========================================================================
   1116  * FUNCTION   : stop_after_set_params
   1117  *
   1118  * DESCRIPTION: stop after a set param call, if necessary
   1119  *
   1120  * PARAMETERS :
   1121  *   @device  : ptr to camera device struct
   1122  *
   1123  * RETURN     : int32_t type of status
   1124  *              NO_ERROR  -- success
   1125  *              none-zero failure code
   1126  *==========================================================================*/
   1127 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
   1128 {
   1129     ATRACE_CALL();
   1130     int ret = NO_ERROR;
   1131     QCamera2HardwareInterface *hw =
   1132         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1133     if (!hw) {
   1134         LOGE("NULL camera device");
   1135         return BAD_VALUE;
   1136     }
   1137     LOGD("E camera id %d", hw->getCameraId());
   1138     hw->lockAPI();
   1139     qcamera_api_result_t apiResult;
   1140 
   1141     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1142         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
   1143         if (ret == NO_ERROR) {
   1144             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
   1145             ret = apiResult.status;
   1146         }
   1147     } else {
   1148         LOGE("is not supposed to be called in single-camera mode");
   1149         ret = INVALID_OPERATION;
   1150     }
   1151 
   1152     hw->unlockAPI();
   1153     LOGD("X camera id %d", hw->getCameraId());
   1154 
   1155     return ret;
   1156 }
   1157 
   1158 /*===========================================================================
   1159  * FUNCTION   : commit_params
   1160  *
   1161  * DESCRIPTION: commit after a set param call
   1162  *
   1163  * PARAMETERS :
   1164  *   @device  : ptr to camera device struct
   1165  *
   1166  * RETURN     : int32_t type of status
   1167  *              NO_ERROR  -- success
   1168  *              none-zero failure code
   1169  *==========================================================================*/
   1170 int QCamera2HardwareInterface::commit_params(struct camera_device *device)
   1171 {
   1172     ATRACE_CALL();
   1173     int ret = NO_ERROR;
   1174     QCamera2HardwareInterface *hw =
   1175         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1176     if (!hw) {
   1177         LOGE("NULL camera device");
   1178         return BAD_VALUE;
   1179     }
   1180     LOGD("E camera id %d", hw->getCameraId());
   1181     hw->lockAPI();
   1182     qcamera_api_result_t apiResult;
   1183 
   1184     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1185         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
   1186         if (ret == NO_ERROR) {
   1187             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
   1188             ret = apiResult.status;
   1189         }
   1190     } else {
   1191         LOGE("is not supposed to be called in single-camera mode");
   1192         ret = INVALID_OPERATION;
   1193     }
   1194 
   1195     hw->unlockAPI();
   1196     LOGD("X camera id %d", hw->getCameraId());
   1197 
   1198     return ret;
   1199 }
   1200 
   1201 /*===========================================================================
   1202  * FUNCTION   : restart_after_set_params
   1203  *
   1204  * DESCRIPTION: restart after a set param call, if necessary
   1205  *
   1206  * PARAMETERS :
   1207  *   @device  : ptr to camera device struct
   1208  *
   1209  * RETURN     : int32_t type of status
   1210  *              NO_ERROR  -- success
   1211  *              none-zero failure code
   1212  *==========================================================================*/
   1213 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
   1214 {
   1215     ATRACE_CALL();
   1216     int ret = NO_ERROR;
   1217     QCamera2HardwareInterface *hw =
   1218         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1219     if (!hw) {
   1220         LOGE("NULL camera device");
   1221         return BAD_VALUE;
   1222     }
   1223     LOGD("E camera id %d", hw->getCameraId());
   1224     hw->lockAPI();
   1225     qcamera_api_result_t apiResult;
   1226 
   1227     if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   1228         ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
   1229         if (ret == NO_ERROR) {
   1230             hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
   1231             ret = apiResult.status;
   1232         }
   1233     } else {
   1234         LOGE("is not supposed to be called in single-camera mode");
   1235         ret = INVALID_OPERATION;
   1236     }
   1237 
   1238     hw->unlockAPI();
   1239     LOGD("X camera id %d", hw->getCameraId());
   1240     return ret;
   1241 }
   1242 
   1243 /*===========================================================================
   1244  * FUNCTION   : get_parameters
   1245  *
   1246  * DESCRIPTION: query camera parameters
   1247  *
   1248  * PARAMETERS :
   1249  *   @device  : ptr to camera device struct
   1250  *
   1251  * RETURN     : packed parameters in a string
   1252  *==========================================================================*/
   1253 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
   1254 {
   1255     ATRACE_CALL();
   1256     char *ret = NULL;
   1257     QCamera2HardwareInterface *hw =
   1258         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1259     if (!hw) {
   1260         LOGE("NULL camera device");
   1261         return NULL;
   1262     }
   1263     LOGD("E camera id %d", hw->getCameraId());
   1264     hw->lockAPI();
   1265     qcamera_api_result_t apiResult;
   1266     int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
   1267     if (rc == NO_ERROR) {
   1268         hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
   1269         ret = apiResult.params;
   1270     }
   1271     hw->unlockAPI();
   1272     LOGD("E camera id %d", hw->getCameraId());
   1273 
   1274     return ret;
   1275 }
   1276 
   1277 /*===========================================================================
   1278  * FUNCTION   : put_parameters
   1279  *
   1280  * DESCRIPTION: return camera parameters string back to HAL
   1281  *
   1282  * PARAMETERS :
   1283  *   @device  : ptr to camera device struct
   1284  *   @parm    : ptr to parameter string to be returned
   1285  *
   1286  * RETURN     : none
   1287  *==========================================================================*/
   1288 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
   1289                                                char *parm)
   1290 {
   1291     ATRACE_CALL();
   1292     QCamera2HardwareInterface *hw =
   1293         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1294     if (!hw) {
   1295         LOGE("NULL camera device");
   1296         return;
   1297     }
   1298     LOGD("E camera id %d", hw->getCameraId());
   1299     hw->lockAPI();
   1300     qcamera_api_result_t apiResult;
   1301     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
   1302     if (ret == NO_ERROR) {
   1303         hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
   1304     }
   1305     hw->unlockAPI();
   1306     LOGD("E camera id %d", hw->getCameraId());
   1307 }
   1308 
   1309 /*===========================================================================
   1310  * FUNCTION   : send_command
   1311  *
   1312  * DESCRIPTION: command to be executed
   1313  *
   1314  * PARAMETERS :
   1315  *   @device  : ptr to camera device struct
   1316  *   @cmd     : cmd to be executed
   1317  *   @arg1    : ptr to optional argument1
   1318  *   @arg2    : ptr to optional argument2
   1319  *
   1320  * RETURN     : int32_t type of status
   1321  *              NO_ERROR  -- success
   1322  *              none-zero failure code
   1323  *==========================================================================*/
   1324 int QCamera2HardwareInterface::send_command(struct camera_device *device,
   1325                                             int32_t cmd,
   1326                                             int32_t arg1,
   1327                                             int32_t arg2)
   1328 {
   1329     ATRACE_CALL();
   1330     int ret = NO_ERROR;
   1331     QCamera2HardwareInterface *hw =
   1332         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1333     if (!hw) {
   1334         LOGE("NULL camera device");
   1335         return BAD_VALUE;
   1336     }
   1337     LOGD("E camera id %d", hw->getCameraId());
   1338 
   1339     qcamera_sm_evt_command_payload_t payload;
   1340     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
   1341     payload.cmd = cmd;
   1342     payload.arg1 = arg1;
   1343     payload.arg2 = arg2;
   1344     hw->lockAPI();
   1345     qcamera_api_result_t apiResult;
   1346     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
   1347     if (ret == NO_ERROR) {
   1348         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
   1349         ret = apiResult.status;
   1350     }
   1351     hw->unlockAPI();
   1352     LOGD("E camera id %d", hw->getCameraId());
   1353 
   1354     return ret;
   1355 }
   1356 
   1357 /*===========================================================================
   1358  * FUNCTION   : send_command_restart
   1359  *
   1360  * DESCRIPTION: restart if necessary after a send_command
   1361  *
   1362  * PARAMETERS :
   1363  *   @device  : ptr to camera device struct
   1364  *   @cmd     : cmd to be executed
   1365  *   @arg1    : ptr to optional argument1
   1366  *   @arg2    : ptr to optional argument2
   1367  *
   1368  * RETURN     : int32_t type of status
   1369  *              NO_ERROR  -- success
   1370  *              none-zero failure code
   1371  *==========================================================================*/
   1372 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
   1373         int32_t cmd,
   1374         int32_t arg1,
   1375         int32_t arg2)
   1376 {
   1377     ATRACE_CALL();
   1378     int ret = NO_ERROR;
   1379     QCamera2HardwareInterface *hw =
   1380             reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1381     if (!hw) {
   1382         LOGE("NULL camera device");
   1383         return BAD_VALUE;
   1384     }
   1385 
   1386     qcamera_sm_evt_command_payload_t payload;
   1387     memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
   1388     payload.cmd = cmd;
   1389     payload.arg1 = arg1;
   1390     payload.arg2 = arg2;
   1391     hw->lockAPI();
   1392     qcamera_api_result_t apiResult;
   1393     ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
   1394     if (ret == NO_ERROR) {
   1395         hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
   1396         ret = apiResult.status;
   1397     }
   1398     hw->unlockAPI();
   1399     LOGD("E camera id %d", hw->getCameraId());
   1400 
   1401     return ret;
   1402 }
   1403 
   1404 /*===========================================================================
   1405  * FUNCTION   : release
   1406  *
   1407  * DESCRIPTION: release camera resource
   1408  *
   1409  * PARAMETERS :
   1410  *   @device  : ptr to camera device struct
   1411  *
   1412  * RETURN     : none
   1413  *==========================================================================*/
   1414 void QCamera2HardwareInterface::release(struct camera_device *device)
   1415 {
   1416     ATRACE_CALL();
   1417     QCamera2HardwareInterface *hw =
   1418         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1419     if (!hw) {
   1420         LOGE("NULL camera device");
   1421         return;
   1422     }
   1423     LOGD("E camera id %d", hw->getCameraId());
   1424     hw->lockAPI();
   1425     qcamera_api_result_t apiResult;
   1426     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
   1427     if (ret == NO_ERROR) {
   1428         hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
   1429     }
   1430     hw->unlockAPI();
   1431     LOGD("E camera id %d", hw->getCameraId());
   1432 }
   1433 
   1434 /*===========================================================================
   1435  * FUNCTION   : dump
   1436  *
   1437  * DESCRIPTION: dump camera status
   1438  *
   1439  * PARAMETERS :
   1440  *   @device  : ptr to camera device struct
   1441  *   @fd      : fd for status to be dumped to
   1442  *
   1443  * RETURN     : int32_t type of status
   1444  *              NO_ERROR  -- success
   1445  *              none-zero failure code
   1446  *==========================================================================*/
   1447 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
   1448 {
   1449     int ret = NO_ERROR;
   1450 
   1451     //Log level property is read when "adb shell dumpsys media.camera" is
   1452     //called so that the log level can be controlled without restarting
   1453     //media server
   1454     getLogLevel();
   1455     QCamera2HardwareInterface *hw =
   1456         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1457     if (!hw) {
   1458         LOGE("NULL camera device");
   1459         return BAD_VALUE;
   1460     }
   1461     LOGD("E camera id %d", hw->getCameraId());
   1462     hw->lockAPI();
   1463     qcamera_api_result_t apiResult;
   1464     ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
   1465     if (ret == NO_ERROR) {
   1466         hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
   1467         ret = apiResult.status;
   1468     }
   1469     hw->unlockAPI();
   1470     LOGD("E camera id %d", hw->getCameraId());
   1471 
   1472     return ret;
   1473 }
   1474 
   1475 /*===========================================================================
   1476  * FUNCTION   : close_camera_device
   1477  *
   1478  * DESCRIPTION: close camera device
   1479  *
   1480  * PARAMETERS :
   1481  *   @device  : ptr to camera device struct
   1482  *
   1483  * RETURN     : int32_t type of status
   1484  *              NO_ERROR  -- success
   1485  *              none-zero failure code
   1486  *==========================================================================*/
   1487 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
   1488 {
   1489     KPI_ATRACE_CALL();
   1490     int ret = NO_ERROR;
   1491 
   1492     QCamera2HardwareInterface *hw =
   1493         reinterpret_cast<QCamera2HardwareInterface *>(
   1494             reinterpret_cast<camera_device_t *>(hw_dev)->priv);
   1495     if (!hw) {
   1496         LOGE("NULL camera device");
   1497         return BAD_VALUE;
   1498     }
   1499     LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
   1500     delete hw;
   1501     LOGI("[KPI Perf]: X");
   1502     return ret;
   1503 }
   1504 
   1505 /*===========================================================================
   1506  * FUNCTION   : register_face_image
   1507  *
   1508  * DESCRIPTION: register a face image into imaging lib for face authenticatio/
   1509  *              face recognition
   1510  *
   1511  * PARAMETERS :
   1512  *   @device  : ptr to camera device struct
   1513  *   @img_ptr : ptr to image buffer
   1514  *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
   1515  *
   1516  * RETURN     : >=0 unique ID of face registerd.
   1517  *              <0  failure.
   1518  *==========================================================================*/
   1519 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
   1520                                                    void *img_ptr,
   1521                                                    cam_pp_offline_src_config_t *config)
   1522 {
   1523     ATRACE_CALL();
   1524     int ret = NO_ERROR;
   1525     QCamera2HardwareInterface *hw =
   1526         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1527     if (!hw) {
   1528         LOGE("NULL camera device");
   1529         return BAD_VALUE;
   1530     }
   1531     LOGD("E camera id %d", hw->getCameraId());
   1532     qcamera_sm_evt_reg_face_payload_t payload;
   1533     memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
   1534     payload.img_ptr = img_ptr;
   1535     payload.config = config;
   1536     hw->lockAPI();
   1537     qcamera_api_result_t apiResult;
   1538     ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
   1539     if (ret == NO_ERROR) {
   1540         hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
   1541         ret = apiResult.handle;
   1542     }
   1543     hw->unlockAPI();
   1544     LOGD("E camera id %d", hw->getCameraId());
   1545 
   1546     return ret;
   1547 }
   1548 
   1549 /*===========================================================================
   1550  * FUNCTION   : prepare_snapshot
   1551  *
   1552  * DESCRIPTION: prepares hardware for snapshot
   1553  *
   1554  * PARAMETERS :
   1555  *   @device  : ptr to camera device struct
   1556  *
   1557  * RETURN     : int32_t type of status
   1558  *              NO_ERROR  -- success
   1559  *              none-zero failure code
   1560  *==========================================================================*/
   1561 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
   1562 {
   1563     ATRACE_CALL();
   1564     int ret = NO_ERROR;
   1565     QCamera2HardwareInterface *hw =
   1566         reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
   1567     if (!hw) {
   1568         LOGE("NULL camera device");
   1569         return BAD_VALUE;
   1570     }
   1571     if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
   1572         // For longshot mode, we prepare snapshot only once
   1573         LOGH("prepare snapshot only once ");
   1574         return NO_ERROR;
   1575     }
   1576     LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
   1577              hw->getCameraId());
   1578     hw->lockAPI();
   1579     qcamera_api_result_t apiResult;
   1580 
   1581     /* Prepare snapshot in case LED needs to be flashed */
   1582     if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
   1583         /* Prepare snapshot in case LED needs to be flashed */
   1584         ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
   1585         if (ret == NO_ERROR) {
   1586           hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
   1587             ret = apiResult.status;
   1588         }
   1589         hw->mPrepSnapRun = true;
   1590     }
   1591     hw->unlockAPI();
   1592     LOGH("[KPI Perf]: X, ret: %d", ret);
   1593     return ret;
   1594 }
   1595 
   1596 /*===========================================================================
   1597  * FUNCTION   : QCamera2HardwareInterface
   1598  *
   1599  * DESCRIPTION: constructor of QCamera2HardwareInterface
   1600  *
   1601  * PARAMETERS :
   1602  *   @cameraId  : camera ID
   1603  *
   1604  * RETURN     : none
   1605  *==========================================================================*/
   1606 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
   1607     : mCameraId(cameraId),
   1608       mCameraHandle(NULL),
   1609       mCameraOpened(false),
   1610       mDualCamera(false),
   1611       m_bRelCamCalibValid(false),
   1612       mPreviewWindow(NULL),
   1613       mMsgEnabled(0),
   1614       mStoreMetaDataInFrame(0),
   1615       mJpegCb(NULL),
   1616       mCallbackCookie(NULL),
   1617       mJpegCallbackCookie(NULL),
   1618       m_bMpoEnabled(TRUE),
   1619       m_stateMachine(this),
   1620       m_smThreadActive(true),
   1621       m_postprocessor(this),
   1622       m_thermalAdapter(QCameraThermalAdapter::getInstance()),
   1623       m_cbNotifier(this),
   1624       m_bPreviewStarted(false),
   1625       m_bRecordStarted(false),
   1626       m_currentFocusState(CAM_AF_STATE_INACTIVE),
   1627       mDumpFrmCnt(0U),
   1628       mDumpSkipCnt(0U),
   1629       mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
   1630       mActiveAF(false),
   1631       m_HDRSceneEnabled(false),
   1632       mLongshotEnabled(false),
   1633       mLiveSnapshotThread(0),
   1634       mIntPicThread(0),
   1635       mFlashNeeded(false),
   1636       mFlashConfigured(false),
   1637       mDeviceRotation(0U),
   1638       mCaptureRotation(0U),
   1639       mJpegExifRotation(0U),
   1640       mUseJpegExifRotation(false),
   1641       mIs3ALocked(false),
   1642       mPrepSnapRun(false),
   1643       mZoomLevel(0),
   1644       mPreviewRestartNeeded(false),
   1645       mVFrameCount(0),
   1646       mVLastFrameCount(0),
   1647       mVLastFpsTime(0),
   1648       mVFps(0),
   1649       mPFrameCount(0),
   1650       mPLastFrameCount(0),
   1651       mPLastFpsTime(0),
   1652       mPFps(0),
   1653       mLowLightConfigured(false),
   1654       mInstantAecFrameCount(0),
   1655       m_bIntJpegEvtPending(false),
   1656       m_bIntRawEvtPending(false),
   1657       mReprocJob(0),
   1658       mJpegJob(0),
   1659       mMetadataAllocJob(0),
   1660       mInitPProcJob(0),
   1661       mParamAllocJob(0),
   1662       mParamInitJob(0),
   1663       mOutputCount(0),
   1664       mInputCount(0),
   1665       mAdvancedCaptureConfigured(false),
   1666       mHDRBracketingEnabled(false),
   1667       mNumPreviewFaces(-1),
   1668       mJpegClientHandle(0),
   1669       mJpegHandleOwner(false),
   1670       mMetadataMem(NULL),
   1671       mCACDoneReceived(false),
   1672       m_bNeedRestart(false),
   1673       mBootToMonoTimestampOffset(0),
   1674       bDepthAFCallbacks(true)
   1675 {
   1676 #ifdef TARGET_TS_MAKEUP
   1677     memset(&mFaceRect, -1, sizeof(mFaceRect));
   1678 #endif
   1679     getLogLevel();
   1680     ATRACE_CALL();
   1681     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
   1682     mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
   1683     mCameraDevice.common.close = close_camera_device;
   1684     mCameraDevice.ops = &mCameraOps;
   1685     mCameraDevice.priv = this;
   1686 
   1687     mDualCamera = is_dual_camera_by_idx(cameraId);
   1688 
   1689     pthread_mutex_init(&m_lock, NULL);
   1690     pthread_cond_init(&m_cond, NULL);
   1691 
   1692     m_apiResultList = NULL;
   1693 
   1694     pthread_mutex_init(&m_evtLock, NULL);
   1695     pthread_cond_init(&m_evtCond, NULL);
   1696     memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
   1697 
   1698 
   1699     pthread_mutex_init(&m_int_lock, NULL);
   1700     pthread_cond_init(&m_int_cond, NULL);
   1701 
   1702     memset(m_channels, 0, sizeof(m_channels));
   1703 
   1704     memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
   1705 
   1706     memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
   1707 
   1708     memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
   1709     memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
   1710     memset(&mJpegHandle, 0, sizeof(mJpegHandle));
   1711     memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
   1712 
   1713     mDeferredWorkThread.launch(deferredWorkRoutine, this);
   1714     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
   1715     m_perfLock.lock_init();
   1716 
   1717     pthread_mutex_init(&mGrallocLock, NULL);
   1718     mEnqueuedBuffers = 0;
   1719     mFrameSkipStart = 0;
   1720     mFrameSkipEnd = 0;
   1721     mLastPreviewFrameID = 0;
   1722 
   1723     //Load and read GPU library.
   1724     lib_surface_utils = NULL;
   1725     LINK_get_surface_pixel_alignment = NULL;
   1726     mSurfaceStridePadding = CAM_PAD_TO_32;
   1727     lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
   1728     if (lib_surface_utils) {
   1729         *(void **)&LINK_get_surface_pixel_alignment =
   1730                 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
   1731          if (LINK_get_surface_pixel_alignment) {
   1732              mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
   1733          }
   1734          dlclose(lib_surface_utils);
   1735     }
   1736     prev_zoomLevel = 0;
   1737 }
   1738 
   1739 /*===========================================================================
   1740  * FUNCTION   : ~QCamera2HardwareInterface
   1741  *
   1742  * DESCRIPTION: destructor of QCamera2HardwareInterface
   1743  *
   1744  * PARAMETERS : none
   1745  *
   1746  * RETURN     : none
   1747  *==========================================================================*/
   1748 QCamera2HardwareInterface::~QCamera2HardwareInterface()
   1749 {
   1750     LOGH("E");
   1751 
   1752     mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
   1753     mDeferredWorkThread.exit();
   1754 
   1755     if (mMetadataMem != NULL) {
   1756         delete mMetadataMem;
   1757         mMetadataMem = NULL;
   1758     }
   1759 
   1760     m_perfLock.lock_acq();
   1761     lockAPI();
   1762     m_smThreadActive = false;
   1763     unlockAPI();
   1764     m_stateMachine.releaseThread();
   1765     closeCamera();
   1766     m_perfLock.lock_rel();
   1767     m_perfLock.lock_deinit();
   1768     pthread_mutex_destroy(&m_lock);
   1769     pthread_cond_destroy(&m_cond);
   1770     pthread_mutex_destroy(&m_evtLock);
   1771     pthread_cond_destroy(&m_evtCond);
   1772     pthread_mutex_destroy(&m_int_lock);
   1773     pthread_cond_destroy(&m_int_cond);
   1774     pthread_mutex_destroy(&mGrallocLock);
   1775     LOGH("X");
   1776 }
   1777 
   1778 /*===========================================================================
   1779  * FUNCTION   : deferPPInit
   1780  *
   1781  * DESCRIPTION: Queue postproc init task to deferred thread
   1782  *
   1783  * PARAMETERS : none
   1784  *
   1785  * RETURN     : uint32_t job id of pproc init job
   1786  *              0  -- failure
   1787  *==========================================================================*/
   1788 uint32_t QCamera2HardwareInterface::deferPPInit()
   1789 {
   1790     // init pproc
   1791     DeferWorkArgs args;
   1792     DeferPProcInitArgs pprocInitArgs;
   1793 
   1794     memset(&args, 0, sizeof(DeferWorkArgs));
   1795     memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
   1796 
   1797     pprocInitArgs.jpeg_cb = jpegEvtHandle;
   1798     pprocInitArgs.user_data = this;
   1799     args.pprocInitArgs = pprocInitArgs;
   1800 
   1801     return queueDeferredWork(CMD_DEF_PPROC_INIT,
   1802             args);
   1803 }
   1804 
   1805 /*===========================================================================
   1806  * FUNCTION   : openCamera
   1807  *
   1808  * DESCRIPTION: open camera
   1809  *
   1810  * PARAMETERS :
   1811  *   @hw_device  : double ptr for camera device struct
   1812  *
   1813  * RETURN     : int32_t type of status
   1814  *              NO_ERROR  -- success
   1815  *              none-zero failure code
   1816  *==========================================================================*/
   1817 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
   1818 {
   1819     KPI_ATRACE_CALL();
   1820     int rc = NO_ERROR;
   1821     if (mCameraOpened) {
   1822         *hw_device = NULL;
   1823         LOGE("Permission Denied");
   1824         return PERMISSION_DENIED;
   1825     }
   1826     LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
   1827             mCameraId);
   1828     m_perfLock.lock_acq_timed(CAMERA_OPEN_PERF_TIME_OUT);
   1829     rc = openCamera();
   1830     if (rc == NO_ERROR){
   1831         *hw_device = &mCameraDevice.common;
   1832         if (m_thermalAdapter.init(this) != 0) {
   1833           LOGW("Init thermal adapter failed");
   1834         }
   1835     }
   1836     else
   1837         *hw_device = NULL;
   1838 
   1839     LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
   1840             mCameraId, rc);
   1841 
   1842     return rc;
   1843 }
   1844 
   1845 /*===========================================================================
   1846  * FUNCTION   : openCamera
   1847  *
   1848  * DESCRIPTION: open camera
   1849  *
   1850  * PARAMETERS : none
   1851  *
   1852  * RETURN     : int32_t type of status
   1853  *              NO_ERROR  -- success
   1854  *              none-zero failure code
   1855  *==========================================================================*/
   1856 int QCamera2HardwareInterface::openCamera()
   1857 {
   1858     int32_t rc = NO_ERROR;
   1859     char value[PROPERTY_VALUE_MAX];
   1860 
   1861     if (mCameraHandle) {
   1862         LOGE("Failure: Camera already opened");
   1863         return ALREADY_EXISTS;
   1864     }
   1865 
   1866     rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
   1867     if (rc < 0) {
   1868         LOGE("Failed to reserve flash for camera id: %d",
   1869                 mCameraId);
   1870         return UNKNOWN_ERROR;
   1871     }
   1872 
   1873     // alloc param buffer
   1874     DeferWorkArgs args;
   1875     memset(&args, 0, sizeof(args));
   1876     mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
   1877     if (mParamAllocJob == 0) {
   1878         LOGE("Failed queueing PARAM_ALLOC job");
   1879         return -ENOMEM;
   1880     }
   1881 
   1882     if (gCamCapability[mCameraId] != NULL) {
   1883         // allocate metadata buffers
   1884         DeferWorkArgs args;
   1885         DeferMetadataAllocArgs metadataAllocArgs;
   1886 
   1887         memset(&args, 0, sizeof(args));
   1888         memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
   1889 
   1890         uint32_t padding =
   1891                 gCamCapability[mCameraId]->padding_info.plane_padding;
   1892         metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
   1893                 padding);
   1894         metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
   1895         args.metadataAllocArgs = metadataAllocArgs;
   1896 
   1897         mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
   1898         if (mMetadataAllocJob == 0) {
   1899             LOGE("Failed to allocate metadata buffer");
   1900             rc = -ENOMEM;
   1901             goto error_exit1;
   1902         }
   1903 
   1904         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
   1905         if (rc) {
   1906             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
   1907                      rc, mCameraHandle);
   1908             goto error_exit2;
   1909         }
   1910 
   1911         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
   1912                 camEvtHandle,
   1913                 (void *) this);
   1914     } else {
   1915         LOGH("Capabilities not inited, initializing now.");
   1916 
   1917         rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
   1918         if (rc) {
   1919             LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
   1920                      rc, mCameraHandle);
   1921             goto error_exit2;
   1922         }
   1923 
   1924         if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
   1925             LOGE("initCapabilities failed.");
   1926             rc = UNKNOWN_ERROR;
   1927             goto error_exit3;
   1928         }
   1929 
   1930         mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
   1931                 camEvtHandle,
   1932                 (void *) this);
   1933     }
   1934 
   1935     mActiveCamera = MM_CAMERA_TYPE_MAIN;
   1936     if (isDualCamera()) {
   1937         mActiveCamera |= MM_CAMERA_TYPE_AUX;
   1938     }
   1939 
   1940     // Init params in the background
   1941     // 1. It's safe to queue init job, even if alloc job is not yet complete.
   1942     // It will be queued to the same thread, so the alloc is guaranteed to
   1943     // finish first.
   1944     // 2. However, it is not safe to begin param init until after camera is
   1945     // open. That is why we wait until after camera open completes to schedule
   1946     // this task.
   1947     memset(&args, 0, sizeof(args));
   1948     mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
   1949     if (mParamInitJob == 0) {
   1950         LOGE("Failed queuing PARAM_INIT job");
   1951         rc = -ENOMEM;
   1952         goto error_exit3;
   1953     }
   1954 
   1955     mCameraOpened = true;
   1956 
   1957     //Notify display HAL that a camera session is active.
   1958     //But avoid calling the same during bootup because camera service might open/close
   1959     //cameras at boot time during its initialization and display service will also internally
   1960     //wait for camera service to initialize first while calling this display API, resulting in a
   1961     //deadlock situation. Since boot time camera open/close calls are made only to fetch
   1962     //capabilities, no need of this display bw optimization.
   1963     //Use "service.bootanim.exit" property to know boot status.
   1964     property_get("service.bootanim.exit", value, "0");
   1965     if (atoi(value) == 1) {
   1966         pthread_mutex_lock(&gCamLock);
   1967         if (gNumCameraSessions++ == 0) {
   1968             setCameraLaunchStatus(true);
   1969         }
   1970         pthread_mutex_unlock(&gCamLock);
   1971     }
   1972 
   1973     // Setprop to decide the time source (whether boottime or monotonic).
   1974     // By default, use monotonic time.
   1975     property_get("persist.camera.time.monotonic", value, "1");
   1976     mBootToMonoTimestampOffset = 0;
   1977     if (atoi(value) == 1) {
   1978         // if monotonic is set, then need to use time in monotonic.
   1979         // So, Measure the clock offset between BOOTTIME and MONOTONIC
   1980         // The clock domain source for ISP is BOOTTIME and
   1981         // for Video/display is MONOTONIC
   1982         // The below offset is used to convert from clock domain of other subsystem
   1983         // (video/hardware composer) to that of camera. Assumption is that this
   1984         // offset won't change during the life cycle of the camera device. In other
   1985         // words, camera device shouldn't be open during CPU suspend.
   1986         mBootToMonoTimestampOffset = getBootToMonoTimeOffset();
   1987     }
   1988     LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset);
   1989 
   1990     memset(value, 0, sizeof(value));
   1991     property_get("persist.camera.depth.focus.cb", value, "1");
   1992     bDepthAFCallbacks = atoi(value);
   1993 
   1994     return NO_ERROR;
   1995 
   1996 error_exit3:
   1997     if(mJpegClientHandle) {
   1998         deinitJpegHandle();
   1999     }
   2000     mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
   2001     mCameraHandle = NULL;
   2002 error_exit2:
   2003     waitDeferredWork(mMetadataAllocJob);
   2004 error_exit1:
   2005     waitDeferredWork(mParamAllocJob);
   2006     return rc;
   2007 
   2008 }
   2009 
   2010 /*===========================================================================
   2011  * FUNCTION   : bundleRelatedCameras
   2012  *
   2013  * DESCRIPTION: bundle cameras to enable syncing of cameras
   2014  *
   2015  * PARAMETERS :
   2016  *   @sync        :indicates whether syncing is On or Off
   2017  *   @sessionid  :session id for other camera session
   2018  *
   2019  * RETURN     : int32_t type of status
   2020  *              NO_ERROR  -- success
   2021  *              none-zero failure code
   2022  *==========================================================================*/
   2023 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn,
   2024             uint32_t sessionid)
   2025 {
   2026     LOGD("bundleRelatedCameras sync %d with sessionid %d",
   2027             syncOn, sessionid);
   2028 
   2029     int32_t rc = mParameters.bundleRelatedCameras(syncOn, sessionid);
   2030     if (rc != NO_ERROR) {
   2031         LOGE("bundleRelatedCameras failed %d", rc);
   2032         return rc;
   2033     }
   2034     return rc;
   2035 }
   2036 
   2037 /*===========================================================================
   2038  * FUNCTION   : getCameraSessionId
   2039  *
   2040  * DESCRIPTION: gets the backend session Id of this HWI instance
   2041  *
   2042  * PARAMETERS :
   2043  *   @sessionid  : pointer to the output session id
   2044  *
   2045  * RETURN     : int32_t type of status
   2046  *              NO_ERROR  -- success
   2047  *              none-zero failure code
   2048  *==========================================================================*/
   2049 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
   2050 {
   2051     int32_t rc = NO_ERROR;
   2052 
   2053     if(session_id != NULL) {
   2054         rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
   2055                 session_id);
   2056         LOGD("Getting Camera Session Id %d", *session_id);
   2057     } else {
   2058         LOGE("Session Id is Null");
   2059         return UNKNOWN_ERROR;
   2060     }
   2061     return rc;
   2062 }
   2063 
   2064 /*===========================================================================
   2065  * FUNCTION   : isFrameSyncEnabled
   2066  *
   2067  * DESCRIPTION: returns whether frame sync is enabled
   2068  *
   2069  * PARAMETERS : none
   2070  *
   2071  * RETURN     : bool indicating whether frame sync is enabled
   2072  *==========================================================================*/
   2073 bool QCamera2HardwareInterface::isFrameSyncEnabled(void)
   2074 {
   2075     return mParameters.isFrameSyncEnabled();
   2076 }
   2077 
   2078 /*===========================================================================
   2079  * FUNCTION   : setFrameSyncEnabled
   2080  *
   2081  * DESCRIPTION: sets whether frame sync is enabled
   2082  *
   2083  * PARAMETERS :
   2084  *   @enable  : flag whether to enable or disable frame sync
   2085  *
   2086  * RETURN     : int32_t type of status
   2087  *              NO_ERROR  -- success
   2088  *              none-zero failure code
   2089  *==========================================================================*/
   2090 int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable)
   2091 {
   2092     return mParameters.setFrameSyncEnabled(enable);
   2093 }
   2094 
   2095 /*===========================================================================
   2096  * FUNCTION   : getRelatedCamSyncInfo
   2097  *
   2098  * DESCRIPTION:returns the related cam sync info for this HWI instance
   2099  *
   2100  * PARAMETERS :none
   2101  *
   2102  * RETURN     : const pointer to cam_sync_related_sensors_event_info_t
   2103  *==========================================================================*/
   2104 const cam_sync_related_sensors_event_info_t*
   2105         QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
   2106 {
   2107     return mParameters.getRelatedCamSyncInfo();
   2108 }
   2109 
   2110 /*===========================================================================
   2111  * FUNCTION   : setRelatedCamSyncInfo
   2112  *
   2113  * DESCRIPTION:sets the related cam sync info for this HWI instance
   2114  *
   2115  * PARAMETERS :
   2116  *   @info  : ptr to related cam info parameters
   2117  *
   2118  * RETURN     : int32_t type of status
   2119  *              NO_ERROR  -- success
   2120  *              none-zero failure code
   2121  *==========================================================================*/
   2122 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
   2123         cam_sync_related_sensors_event_info_t* info)
   2124 {
   2125     if(info) {
   2126         return mParameters.setRelatedCamSyncInfo(info);
   2127     } else {
   2128         return BAD_TYPE;
   2129     }
   2130 }
   2131 
   2132 /*===========================================================================
   2133  * FUNCTION   : getMpoComposition
   2134  *
   2135  * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
   2136  *                    or not
   2137  *
   2138  * PARAMETERS :none
   2139  *
   2140  * RETURN     : bool indicates whether mpo composition is enabled or not
   2141  *==========================================================================*/
   2142 bool QCamera2HardwareInterface::getMpoComposition(void)
   2143 {
   2144     LOGH("MpoComposition:%d ", m_bMpoEnabled);
   2145     return m_bMpoEnabled;
   2146 }
   2147 
   2148 /*===========================================================================
   2149  * FUNCTION   : setMpoComposition
   2150  *
   2151  * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
   2152  *
   2153  * PARAMETERS :
   2154  *   @enable  : indicates whether Mpo composition enabled or not
   2155  *
   2156  * RETURN     : int32_t type of status
   2157  *              NO_ERROR  -- success
   2158  *              none-zero failure code
   2159  *==========================================================================*/
   2160 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
   2161 {
   2162     // By default set Mpo composition to disable
   2163     m_bMpoEnabled = false;
   2164 
   2165     // Enable Mpo composition only if
   2166     // 1) frame sync is ON between two cameras and
   2167     // 2) any advanced features are not enabled (AOST features) and
   2168     // 3) not in recording mode (for liveshot case)
   2169     // 4) flash is not needed
   2170     if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
   2171             !mParameters.isAdvCamFeaturesEnabled() &&
   2172             !mParameters.getRecordingHintValue() &&
   2173             !mFlashNeeded &&
   2174             !isLongshotEnabled()) {
   2175         m_bMpoEnabled = enable;
   2176         LOGH("MpoComposition:%d ", m_bMpoEnabled);
   2177         return NO_ERROR;
   2178     } else {
   2179         return BAD_TYPE;
   2180     }
   2181 }
   2182 
   2183 /*===========================================================================
   2184  * FUNCTION   : getRecordingHintValue
   2185  *
   2186  * DESCRIPTION:function to retrieve recording hint value
   2187  *
   2188  * PARAMETERS :none
   2189  *
   2190  * RETURN     : bool indicates whether recording hint is enabled or not
   2191  *==========================================================================*/
   2192 bool QCamera2HardwareInterface::getRecordingHintValue(void)
   2193 {
   2194     return mParameters.getRecordingHintValue();
   2195 }
   2196 
   2197 /*===========================================================================
   2198  * FUNCTION   : setRecordingHintValue
   2199  *
   2200  * DESCRIPTION:set recording hint value
   2201  *
   2202  * PARAMETERS :
   2203  *   @enable  : video hint value
   2204  *
   2205  * RETURN     : int32_t type of status
   2206  *              NO_ERROR  -- success
   2207  *              none-zero failure code
   2208  *==========================================================================*/
   2209 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
   2210 {
   2211     return mParameters.updateRecordingHintValue(value);
   2212 }
   2213 
   2214 /*===========================================================================
   2215  * FUNCTION   : closeCamera
   2216  *
   2217  * DESCRIPTION: close camera
   2218  *
   2219  * PARAMETERS : none
   2220  *
   2221  * RETURN     : int32_t type of status
   2222  *              NO_ERROR  -- success
   2223  *              none-zero failure code
   2224  *==========================================================================*/
   2225 int QCamera2HardwareInterface::closeCamera()
   2226 {
   2227     int rc = NO_ERROR;
   2228     int i;
   2229     char value[PROPERTY_VALUE_MAX];
   2230     LOGI("E");
   2231     if (!mCameraOpened) {
   2232         return NO_ERROR;
   2233     }
   2234     LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
   2235              mCameraId);
   2236 
   2237     // set open flag to false
   2238     mCameraOpened = false;
   2239 
   2240     // Reset Stream config info
   2241     mParameters.setStreamConfigure(false, false, true);
   2242 
   2243     // deinit Parameters
   2244     mParameters.deinit();
   2245 
   2246     // exit notifier
   2247     m_cbNotifier.exit();
   2248 
   2249     // stop and deinit postprocessor
   2250     waitDeferredWork(mReprocJob);
   2251     // Close the JPEG session
   2252     waitDeferredWork(mJpegJob);
   2253     m_postprocessor.stop();
   2254     deinitJpegHandle();
   2255     m_postprocessor.deinit();
   2256     mInitPProcJob = 0; // reset job id, so pproc can be reinited later
   2257 
   2258     m_thermalAdapter.deinit();
   2259 
   2260     // delete all channels if not already deleted
   2261     for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   2262         if (m_channels[i] != NULL) {
   2263             m_channels[i]->stop();
   2264             delete m_channels[i];
   2265             m_channels[i] = NULL;
   2266         }
   2267     }
   2268 
   2269     //free all pending api results here
   2270     if(m_apiResultList != NULL) {
   2271         api_result_list *apiResultList = m_apiResultList;
   2272         api_result_list *apiResultListNext;
   2273         while (apiResultList != NULL) {
   2274             apiResultListNext = apiResultList->next;
   2275             free(apiResultList);
   2276             apiResultList = apiResultListNext;
   2277         }
   2278     }
   2279 
   2280     rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
   2281     mCameraHandle = NULL;
   2282 
   2283     //Notify display HAL that there is no active camera session
   2284     //but avoid calling the same during bootup. Refer to openCamera
   2285     //for more details.
   2286     property_get("service.bootanim.exit", value, "0");
   2287     if (atoi(value) == 1) {
   2288         pthread_mutex_lock(&gCamLock);
   2289         if (--gNumCameraSessions == 0) {
   2290             setCameraLaunchStatus(false);
   2291         }
   2292         pthread_mutex_unlock(&gCamLock);
   2293     }
   2294 
   2295     if (mExifParams.debug_params) {
   2296         free(mExifParams.debug_params);
   2297         mExifParams.debug_params = NULL;
   2298     }
   2299 
   2300     if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
   2301         LOGD("Failed to release flash for camera id: %d",
   2302                 mCameraId);
   2303     }
   2304 
   2305     LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
   2306          mCameraId, rc);
   2307 
   2308     return rc;
   2309 }
   2310 
   2311 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
   2312 
   2313 
   2314 /*===========================================================================
   2315  * FUNCTION   : getCapabilities
   2316  *
   2317  * DESCRIPTION: query camera capability from back-end
   2318  *
   2319  * PARAMETERS :
   2320  *   @ops        : mm-interface ops structure
   2321  *   @cam_handle  : camera handle for which we need capability
   2322  *
   2323  * RETURN     : ptr type of capability structure
   2324  *              capability for success
   2325  *              NULL for failure
   2326  *==========================================================================*/
   2327 cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
   2328         uint32_t cam_handle)
   2329 {
   2330     int rc = NO_ERROR;
   2331     QCameraHeapMemory *capabilityHeap = NULL;
   2332     cam_capability_t *cap_ptr = NULL;
   2333 
   2334     if (ops == NULL) {
   2335         LOGE("Invalid arguments");
   2336         return NULL;
   2337     }
   2338 
   2339     capabilityHeap = new QCameraHeapMemory(1);
   2340     if (capabilityHeap == NULL) {
   2341         LOGE("creation of capabilityHeap failed");
   2342         return NULL;
   2343     }
   2344 
   2345     /* Allocate memory for capability buffer */
   2346     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
   2347     if(rc != OK) {
   2348         LOGE("No memory for cappability");
   2349         goto allocate_failed;
   2350     }
   2351 
   2352     /* Map memory for capability buffer */
   2353     memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
   2354 
   2355     cam_buf_map_type_list bufMapList;
   2356     rc = QCameraBufferMaps::makeSingletonBufMapList(
   2357             CAM_MAPPING_BUF_TYPE_CAPABILITY,
   2358             0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
   2359             0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
   2360             bufMapList, capabilityHeap->getPtr(0));
   2361 
   2362     if (rc == NO_ERROR) {
   2363         rc = ops->map_bufs(cam_handle,
   2364                 &bufMapList);
   2365     }
   2366     if(rc < 0) {
   2367         LOGE("failed to map capability buffer");
   2368         goto map_failed;
   2369     }
   2370 
   2371     /* Query Capability */
   2372     rc = ops->query_capability(cam_handle);
   2373     if(rc < 0) {
   2374         LOGE("failed to query capability");
   2375         rc = FAILED_TRANSACTION;
   2376         goto query_failed;
   2377     }
   2378 
   2379     cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
   2380     if (cap_ptr == NULL) {
   2381         LOGE("out of memory");
   2382         rc = NO_MEMORY;
   2383         goto query_failed;
   2384     }
   2385 
   2386     memset(cap_ptr, 0, sizeof(cam_capability_t));
   2387     memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
   2388 
   2389     int index;
   2390     for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
   2391         cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
   2392         p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
   2393         p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
   2394     }
   2395 
   2396 query_failed:
   2397     ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
   2398 map_failed:
   2399     capabilityHeap->deallocate();
   2400 allocate_failed:
   2401     delete capabilityHeap;
   2402 
   2403     if (rc != NO_ERROR) {
   2404         return NULL;
   2405     } else {
   2406         return cap_ptr;
   2407     }
   2408 }
   2409 
   2410 /*===========================================================================
   2411  * FUNCTION   : initCapabilities
   2412  *
   2413  * DESCRIPTION: initialize camera capabilities in static data struct
   2414  *
   2415  * PARAMETERS :
   2416  *   @cameraId  : camera Id
   2417  *
   2418  * RETURN     : int32_t type of status
   2419  *              NO_ERROR  -- success
   2420  *              none-zero failure code
   2421  *==========================================================================*/
   2422 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
   2423         mm_camera_vtbl_t *cameraHandle)
   2424 {
   2425     ATRACE_CALL();
   2426     int rc = 0;
   2427     uint32_t handle = 0;
   2428 
   2429     rc = camera_open((uint8_t)cameraId, &cameraHandle);
   2430     if (rc) {
   2431         LOGE("camera_open failed. rc = %d", rc);
   2432         goto open_failed;
   2433     }
   2434     if (!cameraHandle) {
   2435         LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
   2436         goto open_failed;
   2437     }
   2438 
   2439     handle = get_main_camera_handle(cameraHandle->camera_handle);
   2440     gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
   2441     if (gCamCapability[cameraId] == NULL) {
   2442         rc = FAILED_TRANSACTION;
   2443         goto failed_op;
   2444     }
   2445 
   2446     if (is_dual_camera_by_idx(cameraId)) {
   2447         handle = get_aux_camera_handle(cameraHandle->camera_handle);
   2448         gCamCapability[cameraId]->aux_cam_cap =
   2449                 getCapabilities(cameraHandle->ops, handle);
   2450         if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
   2451             rc = FAILED_TRANSACTION;
   2452             free(gCamCapability[cameraId]);
   2453             goto failed_op;
   2454         }
   2455     }
   2456 failed_op:
   2457     cameraHandle->ops->close_camera(cameraHandle->camera_handle);
   2458     cameraHandle = NULL;
   2459 open_failed:
   2460     return rc;
   2461 }
   2462 
   2463 /*===========================================================================
   2464  * FUNCTION   : getCapabilities
   2465  *
   2466  * DESCRIPTION: query camera capabilities
   2467  *
   2468  * PARAMETERS :
   2469  *   @cameraId  : camera Id
   2470  *   @info      : camera info struct to be filled in with camera capabilities
   2471  *
   2472  * RETURN     : int type of status
   2473  *              NO_ERROR  -- success
   2474  *              none-zero failure code
   2475  *==========================================================================*/
   2476 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
   2477         struct camera_info *info, cam_sync_type_t *p_cam_type)
   2478 {
   2479     ATRACE_CALL();
   2480     int rc = NO_ERROR;
   2481     struct  camera_info *p_info = NULL;
   2482     pthread_mutex_lock(&gCamLock);
   2483     p_info = get_cam_info(cameraId, p_cam_type);
   2484     p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
   2485     p_info->static_camera_characteristics = NULL;
   2486     memcpy(info, p_info, sizeof (struct camera_info));
   2487     pthread_mutex_unlock(&gCamLock);
   2488     return rc;
   2489 }
   2490 
   2491 /*===========================================================================
   2492  * FUNCTION   : getCamHalCapabilities
   2493  *
   2494  * DESCRIPTION: get the HAL capabilities structure
   2495  *
   2496  * PARAMETERS :
   2497  *   @cameraId  : camera Id
   2498  *
   2499  * RETURN     : capability structure of respective camera
   2500  *
   2501  *==========================================================================*/
   2502 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
   2503 {
   2504     return gCamCapability[mCameraId];
   2505 }
   2506 
   2507 /*===========================================================================
   2508  * FUNCTION   : getBufNumForAux
   2509  *
   2510  * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
   2511  *
   2512  * PARAMETERS :
   2513  *   @stream_type  : type of stream
   2514  *
   2515  * RETURN     : number of buffers needed
   2516  * NOTE     :  Based on the use cases and auxillary camera type,
   2517                     we can decide buffer count
   2518  *==========================================================================*/
   2519 uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
   2520 {
   2521     if (!isDualCamera()) {
   2522         return 0;
   2523     }
   2524 
   2525     uint8_t bufferCnt = 1;
   2526     switch (stream_type) {
   2527     case CAM_STREAM_TYPE_PREVIEW:
   2528     case CAM_STREAM_TYPE_VIDEO:
   2529     case CAM_STREAM_TYPE_SNAPSHOT:
   2530     case CAM_STREAM_TYPE_METADATA:
   2531     case CAM_STREAM_TYPE_CALLBACK:
   2532     case CAM_STREAM_TYPE_ANALYSIS:
   2533     case CAM_STREAM_TYPE_POSTVIEW:
   2534     case CAM_STREAM_TYPE_RAW:
   2535     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2536     case CAM_STREAM_TYPE_DEFAULT:
   2537     case CAM_STREAM_TYPE_MAX:
   2538         //For wide & tele, we use same buffer count premary and aux streams.
   2539         bufferCnt = getBufNumRequired(stream_type);
   2540         break;
   2541     default:
   2542         break;
   2543     }
   2544     LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
   2545     return bufferCnt;
   2546 }
   2547 
   2548 /*===========================================================================
   2549  * FUNCTION   : getBufNumRequired
   2550  *
   2551  * DESCRIPTION: return number of stream buffers needed for given stream type
   2552  *
   2553  * PARAMETERS :
   2554  *   @stream_type  : type of stream
   2555  *
   2556  * RETURN     : number of buffers needed
   2557  *==========================================================================*/
   2558 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
   2559 {
   2560     int bufferCnt = 0;
   2561     int minCaptureBuffers = mParameters.getNumOfSnapshots();
   2562     char value[PROPERTY_VALUE_MAX];
   2563     bool raw_yuv = false;
   2564     int persist_cnt = 0;
   2565     int minPrevFps, maxPrevFps;
   2566 
   2567     int zslQBuffers = mParameters.getZSLQueueDepth();
   2568 
   2569     int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
   2570                             CAMERA_MIN_JPEG_ENCODING_BUFFERS;
   2571 
   2572     int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
   2573                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2574                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2575                        mParameters.getNumOfExtraBuffersForImageProc() +
   2576                        EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2577 
   2578     int minUndequeCount = 0;
   2579     if (!isNoDisplayMode()) {
   2580         if(mPreviewWindow != NULL) {
   2581             if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
   2582                 != 0) {
   2583                 LOGW("get_min_undequeued_buffer_count  failed");
   2584                 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
   2585                 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
   2586                 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
   2587             }
   2588         } else {
   2589             //preview window might not be set at this point. So, query directly
   2590             //from BufferQueue implementation of gralloc buffers.
   2591             //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
   2592             //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
   2593             minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
   2594         }
   2595         if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
   2596             // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
   2597             // and so change the MACRO as per minUndequeCount
   2598             LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
   2599                      minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
   2600         }
   2601     }
   2602 
   2603     LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
   2604             "maxStreamBuf = %d minUndequeCount = %d",
   2605             minCaptureBuffers, zslQBuffers, minCircularBufNum,
   2606             maxStreamBuf, minUndequeCount);
   2607     // Get buffer count for the particular stream type
   2608     switch (stream_type) {
   2609     case CAM_STREAM_TYPE_PREVIEW:
   2610         {
   2611             if (mParameters.isZSLMode()) {
   2612                 // We need to add two extra streming buffers to add
   2613                 // flexibility in forming matched super buf in ZSL queue.
   2614                 // with number being 'zslQBuffers + minCircularBufNum'
   2615                 // we see preview buffers sometimes get dropped at CPP
   2616                 // and super buf is not forming in ZSL Q for long time.
   2617 
   2618                 bufferCnt = zslQBuffers + minCircularBufNum +
   2619                         mParameters.getNumOfExtraBuffersForImageProc() +
   2620                         mParameters.getNumOfExtraBuffersForPreview() +
   2621                         mParameters.getNumOfExtraHDRInBufsIfNeeded();
   2622             } else {
   2623                 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
   2624                         mParameters.getMaxUnmatchedFramesInQueue() +
   2625                         mParameters.getNumOfExtraBuffersForPreview();
   2626             }
   2627             // ISP allocates native preview buffers and so reducing same from HAL allocation
   2628             if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
   2629                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2630 
   2631             // Extra ZSL preview frames are not needed for HFR case.
   2632             // Thumbnail will not be derived from preview for HFR live snapshot case.
   2633             if ((mParameters.getRecordingHintValue() == true)
   2634                     && (!mParameters.isHfrMode())) {
   2635                 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2636             }
   2637             //Adding Extra preview buffers for 60FPS usecase.
   2638             mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
   2639             if (maxPrevFps > CAMERA_DEFAULT_FPS) {
   2640                 bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
   2641             }
   2642 
   2643             // Add the display minUndequeCount count on top of camera requirement
   2644             bufferCnt += minUndequeCount;
   2645 
   2646             property_get("persist.camera.preview_yuv", value, "0");
   2647             persist_cnt = atoi(value);
   2648             if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2649                     && (bufferCnt < persist_cnt)) {
   2650                 bufferCnt = persist_cnt;
   2651             }
   2652         }
   2653         break;
   2654     case CAM_STREAM_TYPE_POSTVIEW:
   2655         {
   2656             bufferCnt = minCaptureBuffers +
   2657                         mParameters.getMaxUnmatchedFramesInQueue() +
   2658                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2659                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2660                         mParameters.getNumOfExtraBuffersForImageProc();
   2661 
   2662             if (bufferCnt > maxStreamBuf) {
   2663                 bufferCnt = maxStreamBuf;
   2664             }
   2665             bufferCnt += minUndequeCount;
   2666         }
   2667         break;
   2668     case CAM_STREAM_TYPE_SNAPSHOT:
   2669         {
   2670             if (mParameters.isZSLMode() || mLongshotEnabled) {
   2671                 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
   2672                         !mLongshotEnabled) {
   2673                     // Single ZSL snapshot case
   2674                     bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
   2675                             mParameters.getNumOfExtraBuffersForImageProc();
   2676                 }
   2677                 else {
   2678                     // ZSL Burst or Longshot case
   2679                     bufferCnt = zslQBuffers + minCircularBufNum +
   2680                             mParameters.getNumOfExtraBuffersForImageProc();
   2681                 }
   2682                 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
   2683                     //ISP allocates native buffers in YUV case
   2684                     bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2685                 }
   2686             } else {
   2687                 bufferCnt = minCaptureBuffers +
   2688                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2689                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2690                             mParameters.getNumOfExtraBuffersForImageProc();
   2691 
   2692                 if (bufferCnt > maxStreamBuf) {
   2693                     bufferCnt = maxStreamBuf;
   2694                 }
   2695             }
   2696         }
   2697         break;
   2698     case CAM_STREAM_TYPE_RAW:
   2699         property_get("persist.camera.raw_yuv", value, "0");
   2700         raw_yuv = atoi(value) > 0 ? true : false;
   2701 
   2702         if (isRdiMode() || raw_yuv) {
   2703             bufferCnt = zslQBuffers + minCircularBufNum;
   2704         } else if (mParameters.isZSLMode()) {
   2705             bufferCnt = zslQBuffers + minCircularBufNum;
   2706             if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
   2707                 //ISP allocates native buffers in YUV case
   2708                 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
   2709             }
   2710 
   2711         } else {
   2712             bufferCnt = minCaptureBuffers +
   2713                         mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2714                         mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2715                         mParameters.getNumOfExtraBuffersForImageProc();
   2716 
   2717             if (bufferCnt > maxStreamBuf) {
   2718                 bufferCnt = maxStreamBuf;
   2719             }
   2720         }
   2721 
   2722         property_get("persist.camera.preview_raw", value, "0");
   2723         persist_cnt = atoi(value);
   2724         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2725                 && (bufferCnt < persist_cnt)) {
   2726             bufferCnt = persist_cnt;
   2727         }
   2728         property_get("persist.camera.video_raw", value, "0");
   2729         persist_cnt = atoi(value);
   2730         if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
   2731                 && (bufferCnt < persist_cnt)) {
   2732             bufferCnt = persist_cnt;
   2733         }
   2734 
   2735         break;
   2736     case CAM_STREAM_TYPE_VIDEO:
   2737         {
   2738             if (mParameters.getBufBatchCount()) {
   2739                 //Video Buffer in case of HFR or camera batching..
   2740                 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
   2741             } else if (mParameters.getVideoBatchSize()) {
   2742                 //Video Buffer count only for HAL to HAL batching.
   2743                 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
   2744                         * mParameters.getVideoBatchSize());
   2745                 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
   2746                     bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
   2747                 }
   2748             } else {
   2749                 // No batching enabled.
   2750                 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
   2751             }
   2752 
   2753             bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
   2754             //if its 4K encoding usecase, then add extra buffer
   2755             cam_dimension_t dim;
   2756             mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
   2757             if (is4k2kResolution(&dim)) {
   2758                  //get additional buffer count
   2759                  property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
   2760                  bufferCnt += atoi(value);
   2761             }
   2762         }
   2763         break;
   2764     case CAM_STREAM_TYPE_METADATA:
   2765         {
   2766             if (mParameters.isZSLMode()) {
   2767                 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
   2768                 bufferCnt = zslQBuffers + minCircularBufNum +
   2769                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2770                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2771                             mParameters.getNumOfExtraBuffersForImageProc() +
   2772                             EXTRA_ZSL_PREVIEW_STREAM_BUF;
   2773             } else {
   2774                 bufferCnt = minCaptureBuffers +
   2775                             mParameters.getNumOfExtraHDRInBufsIfNeeded() -
   2776                             mParameters.getNumOfExtraHDROutBufsIfNeeded() +
   2777                             mParameters.getMaxUnmatchedFramesInQueue() +
   2778                             CAMERA_MIN_STREAMING_BUFFERS +
   2779                             mParameters.getNumOfExtraBuffersForImageProc();
   2780 
   2781                 if (bufferCnt > zslQBuffers + minCircularBufNum) {
   2782                     bufferCnt = zslQBuffers + minCircularBufNum;
   2783                 }
   2784             }
   2785             if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
   2786                 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
   2787             }
   2788         }
   2789         break;
   2790     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2791         {
   2792             bufferCnt = minCaptureBuffers;
   2793             // One of the ubifocus buffers is miscellaneous buffer
   2794             if (mParameters.isUbiRefocus()) {
   2795                 bufferCnt -= 1;
   2796             }
   2797             if (mLongshotEnabled) {
   2798                 bufferCnt = mParameters.getLongshotStages();
   2799             }
   2800         }
   2801         break;
   2802     case CAM_STREAM_TYPE_CALLBACK:
   2803         bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
   2804         break;
   2805     case CAM_STREAM_TYPE_ANALYSIS:
   2806     case CAM_STREAM_TYPE_DEFAULT:
   2807     case CAM_STREAM_TYPE_MAX:
   2808     default:
   2809         bufferCnt = 0;
   2810         break;
   2811     }
   2812 
   2813     LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
   2814     if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
   2815         LOGW("Buffer count %d for stream type %d exceeds limit %d",
   2816                  bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
   2817         return CAM_MAX_NUM_BUFS_PER_STREAM;
   2818     }
   2819 
   2820     return (uint8_t)bufferCnt;
   2821 }
   2822 
   2823 /*===========================================================================
   2824  * FUNCTION   : getStreamRefCount
   2825  *
   2826  * DESCRIPTION: return number of instance of stream of stream type
   2827  *
   2828  * PARAMETERS :
   2829  *   @stream_type  : type of stream
   2830  *
   2831  * RETURN     : number of stream instances
   2832  * NOTE      :  Based on the use cases and auxillary camera type,
   2833                      we can decide stream reference count.
   2834                      For example in wide and tele use case, we duplicate all stream
   2835                      streams from premary to auxillary.
   2836  *==========================================================================*/
   2837 uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type)
   2838 {
   2839     uint8_t ref_cnt = 1;
   2840     switch (stream_type) {
   2841     case CAM_STREAM_TYPE_PREVIEW:
   2842     case CAM_STREAM_TYPE_SNAPSHOT:
   2843     case CAM_STREAM_TYPE_VIDEO:
   2844     case CAM_STREAM_TYPE_METADATA:
   2845     case CAM_STREAM_TYPE_ANALYSIS:
   2846     case CAM_STREAM_TYPE_CALLBACK:
   2847         if (isDualCamera()) {
   2848             ref_cnt++;
   2849         }
   2850         break;
   2851     case CAM_STREAM_TYPE_POSTVIEW:
   2852     case CAM_STREAM_TYPE_RAW:
   2853     case CAM_STREAM_TYPE_OFFLINE_PROC:
   2854     case CAM_STREAM_TYPE_DEFAULT:
   2855     case CAM_STREAM_TYPE_MAX:
   2856     default:
   2857         break;
   2858     }
   2859     return ref_cnt;
   2860 }
   2861 
   2862 /*===========================================================================
   2863  * FUNCTION   : getCamHandleForChannel
   2864  *
   2865  * DESCRIPTION: return actual camera handle based on use case
   2866  *
   2867  * PARAMETERS :
   2868  *   @ch_type  : type of channel
   2869  *
   2870  * RETURN     : uint32_t type camera handle
   2871  * NOTE :  Based on the use cases and auxillary camera type, we can decide cam handle for channel.
   2872                  Incase, we want to avoid any channel for auxillary camera, we can decide here
   2873  *==========================================================================*/
   2874 uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
   2875 {
   2876     uint32_t handle = 0;
   2877     if (!isDualCamera()) {
   2878         return mCameraHandle->camera_handle;
   2879     }
   2880 
   2881     /*Based on the use case, decide camera handle for channel*/
   2882     switch (ch_type) {
   2883     case QCAMERA_CH_TYPE_ZSL:
   2884     case QCAMERA_CH_TYPE_CAPTURE:
   2885     case QCAMERA_CH_TYPE_PREVIEW:
   2886     case QCAMERA_CH_TYPE_VIDEO:
   2887     case QCAMERA_CH_TYPE_SNAPSHOT:
   2888     case QCAMERA_CH_TYPE_RAW:
   2889     case QCAMERA_CH_TYPE_METADATA:
   2890     case QCAMERA_CH_TYPE_ANALYSIS:
   2891     case QCAMERA_CH_TYPE_CALLBACK:
   2892     case QCAMERA_CH_TYPE_MAX:
   2893     default:
   2894         handle = mCameraHandle->camera_handle;
   2895         break;
   2896     case QCAMERA_CH_TYPE_REPROCESSING:
   2897         handle = get_main_camera_handle(mCameraHandle->camera_handle);
   2898         break;
   2899     }
   2900     return handle;
   2901 }
   2902 
   2903 /*===========================================================================
   2904  * FUNCTION   : allocateStreamBuf
   2905  *
   2906  * DESCRIPTION: alocate stream buffers
   2907  *
   2908  * PARAMETERS :
   2909  *   @stream_type  : type of stream
   2910  *   @size         : size of buffer
   2911  *   @stride       : stride of buffer
   2912  *   @scanline     : scanline of buffer
   2913  *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
   2914  *                   could be modified during allocation if more buffers needed
   2915  *
   2916  * RETURN     : ptr to a memory obj that holds stream buffers.
   2917  *              NULL if failed
   2918  *==========================================================================*/
   2919 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
   2920         cam_stream_type_t stream_type, size_t size, int stride, int scanline,
   2921         uint8_t &bufferCnt)
   2922 {
   2923     int rc = NO_ERROR;
   2924     QCameraMemory *mem = NULL;
   2925     bool bCachedMem = QCAMERA_ION_USE_CACHE;
   2926     bool bPoolMem = false;
   2927     char value[PROPERTY_VALUE_MAX];
   2928     property_get("persist.camera.mem.usepool", value, "1");
   2929     if (atoi(value) == 1) {
   2930         bPoolMem = true;
   2931     }
   2932 
   2933     // Allocate stream buffer memory object
   2934     switch (stream_type) {
   2935     case CAM_STREAM_TYPE_PREVIEW:
   2936         {
   2937             if (isNoDisplayMode()) {
   2938                 mem = new QCameraStreamMemory(mGetMemory,
   2939                         bCachedMem,
   2940                         (bPoolMem) ? &m_memoryPool : NULL,
   2941                         stream_type);
   2942             } else {
   2943                 cam_dimension_t dim;
   2944                 int minFPS, maxFPS;
   2945                 QCameraGrallocMemory *grallocMemory =
   2946                     new QCameraGrallocMemory(mGetMemory);
   2947 
   2948                 mParameters.getStreamDimension(stream_type, dim);
   2949                 /* we are interested only in maxfps here */
   2950                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   2951                 int usage = 0;
   2952                 if(mParameters.isUBWCEnabled()) {
   2953                     cam_format_t fmt;
   2954                     mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
   2955                     if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   2956                         usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
   2957                     }
   2958                 }
   2959                 if (grallocMemory) {
   2960                     grallocMemory->setMappable(
   2961                             CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
   2962                     grallocMemory->setWindowInfo(mPreviewWindow,
   2963                             dim.width,dim.height, stride, scanline,
   2964                             mParameters.getPreviewHalPixelFormat(),
   2965                             maxFPS, usage);
   2966                     pthread_mutex_lock(&mGrallocLock);
   2967                     if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
   2968                         mEnqueuedBuffers = (bufferCnt -
   2969                                 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
   2970                     } else {
   2971                         mEnqueuedBuffers = 0;
   2972                     }
   2973                     pthread_mutex_unlock(&mGrallocLock);
   2974                 }
   2975                 mem = grallocMemory;
   2976             }
   2977         }
   2978         break;
   2979     case CAM_STREAM_TYPE_POSTVIEW:
   2980         {
   2981             if (isNoDisplayMode() || isPreviewRestartEnabled()) {
   2982                 mem = new QCameraStreamMemory(mGetMemory, bCachedMem);
   2983             } else {
   2984                 cam_dimension_t dim;
   2985                 int minFPS, maxFPS;
   2986                 QCameraGrallocMemory *grallocMemory =
   2987                         new QCameraGrallocMemory(mGetMemory);
   2988 
   2989                 mParameters.getStreamDimension(stream_type, dim);
   2990                 /* we are interested only in maxfps here */
   2991                 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   2992                 if (grallocMemory) {
   2993                     grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
   2994                             dim.height, stride, scanline,
   2995                             mParameters.getPreviewHalPixelFormat(), maxFPS);
   2996                 }
   2997                 mem = grallocMemory;
   2998             }
   2999         }
   3000         break;
   3001     case CAM_STREAM_TYPE_ANALYSIS:
   3002     case CAM_STREAM_TYPE_SNAPSHOT:
   3003     case CAM_STREAM_TYPE_RAW:
   3004     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3005         mem = new QCameraStreamMemory(mGetMemory,
   3006                 bCachedMem,
   3007                 (bPoolMem) ? &m_memoryPool : NULL,
   3008                 stream_type);
   3009         break;
   3010     case CAM_STREAM_TYPE_METADATA:
   3011         {
   3012             if (mMetadataMem == NULL) {
   3013                 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
   3014             } else {
   3015                 mem = mMetadataMem;
   3016                 mMetadataMem = NULL;
   3017 
   3018                 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
   3019                 if (numAdditionalBuffers > 0) {
   3020                     rc = mem->allocateMore(numAdditionalBuffers, size);
   3021                     if (rc != NO_ERROR) {
   3022                         LOGE("Failed to allocate additional buffers, "
   3023                                 "but attempting to proceed.");
   3024                     }
   3025                 }
   3026                 bufferCnt = mem->getCnt();
   3027                 // The memory is already allocated  and initialized, so
   3028                 // simply return here.
   3029                 return mem;
   3030             }
   3031         }
   3032         break;
   3033     case CAM_STREAM_TYPE_VIDEO:
   3034         {
   3035             //Use uncached allocation by default
   3036             if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
   3037                     mParameters.isHighQualityNoiseReductionMode()) {
   3038                 bCachedMem = QCAMERA_ION_USE_CACHE;
   3039             }
   3040             else {
   3041                 bCachedMem = QCAMERA_ION_USE_NOCACHE;
   3042             }
   3043 
   3044             QCameraVideoMemory *videoMemory = NULL;
   3045             if (mParameters.getVideoBatchSize()) {
   3046                 videoMemory = new QCameraVideoMemory(
   3047                         mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
   3048                 if (videoMemory == NULL) {
   3049                     LOGE("Out of memory for video batching obj");
   3050                     return NULL;
   3051                 }
   3052                 /*
   3053                 *   numFDs = BATCH size
   3054                 *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
   3055                 */
   3056                 rc = videoMemory->allocateMeta(
   3057                         CAMERA_MIN_VIDEO_BATCH_BUFFERS,
   3058                         mParameters.getVideoBatchSize(),
   3059                         VIDEO_METADATA_NUM_INTS);
   3060                 if (rc < 0) {
   3061                     delete videoMemory;
   3062                     return NULL;
   3063                 }
   3064             } else {
   3065                 videoMemory =
   3066                         new QCameraVideoMemory(mGetMemory, bCachedMem);
   3067                 if (videoMemory == NULL) {
   3068                     LOGE("Out of memory for video obj");
   3069                     return NULL;
   3070                 }
   3071             }
   3072 
   3073             int usage = 0;
   3074             cam_format_t fmt;
   3075             mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
   3076             if (mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
   3077                 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   3078             }
   3079             videoMemory->setVideoInfo(usage, fmt);
   3080             mem = videoMemory;
   3081         }
   3082         break;
   3083     case CAM_STREAM_TYPE_CALLBACK:
   3084         mem = new QCameraStreamMemory(mGetMemory,
   3085                 bCachedMem,
   3086                 (bPoolMem) ? &m_memoryPool : NULL,
   3087                 stream_type);
   3088         break;
   3089     case CAM_STREAM_TYPE_DEFAULT:
   3090     case CAM_STREAM_TYPE_MAX:
   3091     default:
   3092         break;
   3093     }
   3094     if (!mem) {
   3095         return NULL;
   3096     }
   3097 
   3098     if (bufferCnt > 0) {
   3099         if (mParameters.isSecureMode() &&
   3100             (stream_type == CAM_STREAM_TYPE_RAW) &&
   3101             (mParameters.isRdiMode())) {
   3102             LOGD("Allocating %d secure buffers of size %d ", bufferCnt, size);
   3103             rc = mem->allocate(bufferCnt, size, SECURE);
   3104         } else {
   3105             rc = mem->allocate(bufferCnt, size, NON_SECURE);
   3106         }
   3107         if (rc < 0) {
   3108             delete mem;
   3109             return NULL;
   3110         }
   3111         bufferCnt = mem->getCnt();
   3112     }
   3113     LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d",
   3114             rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem);
   3115     return mem;
   3116 }
   3117 
   3118 /*===========================================================================
   3119  * FUNCTION   : allocateMoreStreamBuf
   3120  *
   3121  * DESCRIPTION: alocate more stream buffers from the memory object
   3122  *
   3123  * PARAMETERS :
   3124  *   @mem_obj      : memory object ptr
   3125  *   @size         : size of buffer
   3126  *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
   3127  *                   output will be the number of total buffers
   3128  *
   3129  * RETURN     : int32_t type of status
   3130  *              NO_ERROR  -- success
   3131  *              none-zero failure code
   3132  *==========================================================================*/
   3133 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
   3134         QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
   3135 {
   3136     int rc = NO_ERROR;
   3137 
   3138     if (bufferCnt > 0) {
   3139         rc = mem_obj->allocateMore(bufferCnt, size);
   3140         bufferCnt = mem_obj->getCnt();
   3141     }
   3142     return rc;
   3143 }
   3144 
   3145 /*===========================================================================
   3146  * FUNCTION   : allocateMiscBuf
   3147  *
   3148  * DESCRIPTION: alocate miscellaneous buffer
   3149  *
   3150  * PARAMETERS :
   3151  *   @streamInfo  : stream info
   3152  *
   3153  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3154  *              NULL if failed
   3155  *==========================================================================*/
   3156 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
   3157         cam_stream_info_t *streamInfo)
   3158 {
   3159     int rc = NO_ERROR;
   3160     uint8_t bufNum = 0;
   3161     size_t bufSize = 0;
   3162     QCameraHeapMemory *miscBuf = NULL;
   3163     cam_feature_mask_t feature_mask =
   3164             streamInfo->reprocess_config.pp_feature_config.feature_mask;
   3165 
   3166     switch (streamInfo->stream_type) {
   3167     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3168         if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
   3169             bufNum = 1;
   3170             bufSize = mParameters.getTPMaxMetaSize();
   3171         } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
   3172             bufNum = 1;
   3173             bufSize = mParameters.getRefocusMaxMetaSize();
   3174         }
   3175         break;
   3176     default:
   3177         break;
   3178     }
   3179 
   3180     if (bufNum && bufSize) {
   3181         miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   3182 
   3183         if (!miscBuf) {
   3184             LOGE("Unable to allocate miscBuf object");
   3185             return NULL;
   3186         }
   3187 
   3188         rc = miscBuf->allocate(bufNum, bufSize, NON_SECURE);
   3189         if (rc < 0) {
   3190             LOGE("Failed to allocate misc buffer memory");
   3191             delete miscBuf;
   3192             return NULL;
   3193         }
   3194     }
   3195 
   3196     return miscBuf;
   3197 }
   3198 
   3199 /*===========================================================================
   3200  * FUNCTION   : initStreamInfoBuf
   3201  *
   3202  * DESCRIPTION: initialize stream info buffer based on stream type
   3203  *
   3204  * PARAMETERS :
   3205  *   @stream_type  : type of stream
   3206  *
   3207  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3208  *              NULL if failed
   3209  *==========================================================================*/
   3210 int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
   3211             cam_stream_info_t *streamInfo)
   3212 {
   3213     int rc = NO_ERROR;
   3214     int32_t dt = 0;
   3215     int32_t vc = 0;
   3216 
   3217     memset(streamInfo, 0, sizeof(cam_stream_info_t));
   3218     streamInfo->stream_type = stream_type;
   3219     rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
   3220     rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
   3221     rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
   3222     streamInfo->num_bufs = getBufNumRequired(stream_type);
   3223     streamInfo->buf_cnt = streamInfo->num_bufs;
   3224     streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   3225     streamInfo->is_secure = NON_SECURE;
   3226 
   3227     switch (stream_type) {
   3228     case CAM_STREAM_TYPE_SNAPSHOT:
   3229         if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
   3230             mLongshotEnabled) {
   3231             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   3232         } else {
   3233             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   3234             streamInfo->num_of_burst = (uint8_t)
   3235                     (mParameters.getNumOfSnapshots()
   3236                         + mParameters.getNumOfExtraHDRInBufsIfNeeded()
   3237                         - mParameters.getNumOfExtraHDROutBufsIfNeeded()
   3238                         + mParameters.getNumOfExtraBuffersForImageProc());
   3239         }
   3240         break;
   3241     case CAM_STREAM_TYPE_RAW: {
   3242             char value[PROPERTY_VALUE_MAX];
   3243             bool raw_yuv = false;
   3244             property_get("persist.camera.raw_yuv", value, "0");
   3245             raw_yuv = atoi(value) > 0 ? true : false;
   3246             if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) {
   3247                 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   3248             } else {
   3249                 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   3250                 streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
   3251             }
   3252             if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
   3253                 streamInfo->is_secure = SECURE;
   3254             } else {
   3255                 streamInfo->is_secure = NON_SECURE;
   3256             }
   3257         }
   3258         if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
   3259             mParameters.updateDtVc(&dt, &vc);
   3260             if (dt)
   3261                 streamInfo->dt = dt;
   3262             streamInfo->vc = vc;
   3263         }
   3264 
   3265         break;
   3266     case CAM_STREAM_TYPE_POSTVIEW:
   3267         if (mLongshotEnabled) {
   3268             streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
   3269         } else {
   3270             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
   3271             streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
   3272                 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
   3273                 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
   3274                 + mParameters.getNumOfExtraBuffersForImageProc());
   3275         }
   3276         break;
   3277     case CAM_STREAM_TYPE_VIDEO:
   3278         streamInfo->dis_enable = mParameters.isDISEnabled();
   3279         if (mParameters.getBufBatchCount()) {
   3280             //Update stream info structure with batch mode info
   3281             streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
   3282             streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
   3283             streamInfo->user_buf_info.size =
   3284                     (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
   3285             cam_fps_range_t pFpsRange;
   3286             mParameters.getHfrFps(pFpsRange);
   3287             streamInfo->user_buf_info.frameInterval =
   3288                     (long)((1000/pFpsRange.video_max_fps) * 1000);
   3289             LOGH("Video Batch Count = %d, interval = %d",
   3290                     streamInfo->user_buf_info.frame_buf_cnt,
   3291                     streamInfo->user_buf_info.frameInterval);
   3292         }
   3293         if (mParameters.getRecordingHintValue()) {
   3294             if(mParameters.isDISEnabled()) {
   3295                 streamInfo->is_type = mParameters.getVideoISType();
   3296             } else {
   3297                 streamInfo->is_type = IS_TYPE_NONE;
   3298             }
   3299         }
   3300         if (mParameters.isSecureMode()) {
   3301             streamInfo->is_secure = SECURE;
   3302         }
   3303         break;
   3304     case CAM_STREAM_TYPE_PREVIEW:
   3305         if (mParameters.getRecordingHintValue()) {
   3306             if(mParameters.isDISEnabled()) {
   3307                 streamInfo->is_type = mParameters.getPreviewISType();
   3308             } else {
   3309                 streamInfo->is_type = IS_TYPE_NONE;
   3310             }
   3311         }
   3312         if (mParameters.isSecureMode()) {
   3313             streamInfo->is_secure = SECURE;
   3314         }
   3315         break;
   3316     case CAM_STREAM_TYPE_ANALYSIS:
   3317         streamInfo->noFrameExpected = 1;
   3318         break;
   3319     default:
   3320         break;
   3321     }
   3322 
   3323     // Update feature mask
   3324     mParameters.updatePpFeatureMask(stream_type);
   3325 
   3326     // Get feature mask
   3327     mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
   3328 
   3329     // Update pp config
   3330     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
   3331         int flipMode = mParameters.getFlipMode(stream_type);
   3332         if (flipMode > 0) {
   3333             streamInfo->pp_config.flip = (uint32_t)flipMode;
   3334         }
   3335     }
   3336     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
   3337         streamInfo->pp_config.sharpness = mParameters.getSharpness();
   3338     }
   3339     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
   3340         streamInfo->pp_config.effect = mParameters.getEffectValue();
   3341     }
   3342 
   3343     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
   3344         streamInfo->pp_config.denoise2d.denoise_enable = 1;
   3345         streamInfo->pp_config.denoise2d.process_plates =
   3346                 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
   3347     }
   3348 
   3349     if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
   3350             CAM_STREAM_TYPE_RAW == stream_type))) {
   3351         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
   3352                 CAM_QCOM_FEATURE_CROP)
   3353             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   3354         if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
   3355                 CAM_QCOM_FEATURE_SCALE)
   3356             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   3357     }
   3358     streamInfo->aux_str_info = NULL;
   3359 
   3360     LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
   3361            stream_type, streamInfo->fmt, streamInfo->dim.width,
   3362            streamInfo->dim.height, streamInfo->num_bufs,
   3363            streamInfo->pp_config.feature_mask,
   3364            streamInfo->is_type);
   3365 
   3366     return rc;
   3367 }
   3368 
   3369 /*===========================================================================
   3370  * FUNCTION   : allocateStreamInfoBuf
   3371  *
   3372  * DESCRIPTION: alocate stream info buffer
   3373  *
   3374  * PARAMETERS :
   3375  *   @stream_type  : type of stream
   3376  *   @bufCount       : stream info buffer count
   3377  *
   3378  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3379  *              NULL if failed
   3380  *==========================================================================*/
   3381 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
   3382         cam_stream_type_t stream_type, uint8_t bufCount)
   3383 {
   3384     int rc = NO_ERROR;
   3385 
   3386     QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   3387     if (!streamInfoBuf) {
   3388         LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
   3389         return NULL;
   3390     }
   3391 
   3392     if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
   3393         LOGE("buffer count should be lesser than max camera : %d", bufCount);
   3394         return NULL;
   3395     }
   3396     rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t), NON_SECURE);
   3397     if (rc < 0) {
   3398         LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
   3399         delete streamInfoBuf;
   3400         return NULL;
   3401     }
   3402 
   3403     for (uint8_t i = 0; i < bufCount; i++) {
   3404         cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
   3405         memset(streamInfo, 0, sizeof(cam_stream_info_t));
   3406         rc = initStreamInfoBuf(stream_type, streamInfo);
   3407         if (rc < 0) {
   3408             LOGE("initStreamInfoBuf failed");
   3409             delete streamInfoBuf;
   3410             return NULL;
   3411         }
   3412     }
   3413 
   3414     cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
   3415     if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
   3416         cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
   3417         streamInfo->aux_str_info = s_streamInfo;
   3418     }
   3419 
   3420     if (streamInfo->aux_str_info != NULL) {
   3421         /*Update StreamInfo for Aux camera*/
   3422         streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
   3423         streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
   3424         streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
   3425     }
   3426     return streamInfoBuf;
   3427 }
   3428 
   3429 /*===========================================================================
   3430  * FUNCTION   : allocateStreamUserBuf
   3431  *
   3432  * DESCRIPTION: allocate user ptr for stream buffers
   3433  *
   3434  * PARAMETERS :
   3435  *   @streamInfo  : stream info structure
   3436  *
   3437  * RETURN     : ptr to a memory obj that holds stream info buffer.
   3438  *                    NULL if failed
   3439 
   3440  *==========================================================================*/
   3441 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
   3442         cam_stream_info_t *streamInfo)
   3443 {
   3444     int rc = NO_ERROR;
   3445     QCameraMemory *mem = NULL;
   3446     int size = 0;
   3447 
   3448     if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
   3449         LOGE("Stream is not in BATCH mode. Invalid Stream");
   3450         return NULL;
   3451     }
   3452 
   3453     // Allocate stream user buffer memory object
   3454     switch (streamInfo->stream_type) {
   3455     case CAM_STREAM_TYPE_VIDEO: {
   3456         QCameraVideoMemory *video_mem = new QCameraVideoMemory(
   3457                 mGetMemory, FALSE, QCAMERA_MEM_TYPE_BATCH);
   3458         if (video_mem == NULL) {
   3459             LOGE("Out of memory for video obj");
   3460             return NULL;
   3461         }
   3462         /*
   3463         *   numFDs = BATCH size
   3464         *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
   3465         */
   3466         rc = video_mem->allocateMeta(streamInfo->num_bufs,
   3467                 mParameters.getBufBatchCount(), VIDEO_METADATA_NUM_INTS);
   3468         if (rc < 0) {
   3469             LOGE("allocateMeta failed");
   3470             delete video_mem;
   3471             return NULL;
   3472         }
   3473         int usage = 0;
   3474         cam_format_t fmt;
   3475         mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
   3476         if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
   3477             usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   3478         }
   3479         video_mem->setVideoInfo(usage, fmt);
   3480         mem = static_cast<QCameraMemory *>(video_mem);
   3481     }
   3482     break;
   3483 
   3484     case CAM_STREAM_TYPE_PREVIEW:
   3485     case CAM_STREAM_TYPE_POSTVIEW:
   3486     case CAM_STREAM_TYPE_ANALYSIS:
   3487     case CAM_STREAM_TYPE_SNAPSHOT:
   3488     case CAM_STREAM_TYPE_RAW:
   3489     case CAM_STREAM_TYPE_METADATA:
   3490     case CAM_STREAM_TYPE_OFFLINE_PROC:
   3491     case CAM_STREAM_TYPE_CALLBACK:
   3492         LOGE("Stream type Not supported.for BATCH processing");
   3493     break;
   3494 
   3495     case CAM_STREAM_TYPE_DEFAULT:
   3496     case CAM_STREAM_TYPE_MAX:
   3497     default:
   3498         break;
   3499     }
   3500     if (!mem) {
   3501         LOGE("Failed to allocate mem");
   3502         return NULL;
   3503     }
   3504 
   3505     /*Size of this buffer will be number of batch buffer */
   3506     size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
   3507             CAM_PAD_TO_4K);
   3508 
   3509     LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
   3510 
   3511     if (size > 0) {
   3512         // Allocating one buffer for all batch buffers
   3513         rc = mem->allocate(1, size, NON_SECURE);
   3514         if (rc < 0) {
   3515             delete mem;
   3516             return NULL;
   3517         }
   3518     }
   3519     return mem;
   3520 }
   3521 
   3522 
   3523 /*===========================================================================
   3524  * FUNCTION   : waitForDeferredAlloc
   3525  *
   3526  * DESCRIPTION: Wait for deferred allocation, if applicable
   3527  *              (applicable only for metadata buffers so far)
   3528  *
   3529  * PARAMETERS :
   3530  *   @stream_type  : type of stream to (possibly) wait for
   3531  *
   3532  * RETURN     : None
   3533  *==========================================================================*/
   3534 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
   3535 {
   3536     if (stream_type == CAM_STREAM_TYPE_METADATA) {
   3537         waitDeferredWork(mMetadataAllocJob);
   3538     }
   3539 }
   3540 
   3541 
   3542 /*===========================================================================
   3543  * FUNCTION   : setPreviewWindow
   3544  *
   3545  * DESCRIPTION: set preview window impl
   3546  *
   3547  * PARAMETERS :
   3548  *   @window  : ptr to window ops table struct
   3549  *
   3550  * RETURN     : int32_t type of status
   3551  *              NO_ERROR  -- success
   3552  *              none-zero failure code
   3553  *==========================================================================*/
   3554 int QCamera2HardwareInterface::setPreviewWindow(
   3555         struct preview_stream_ops *window)
   3556 {
   3557     mPreviewWindow = window;
   3558     return NO_ERROR;
   3559 }
   3560 
   3561 /*===========================================================================
   3562  * FUNCTION   : setCallBacks
   3563  *
   3564  * DESCRIPTION: set callbacks impl
   3565  *
   3566  * PARAMETERS :
   3567  *   @notify_cb  : notify cb
   3568  *   @data_cb    : data cb
   3569  *   @data_cb_timestamp : data cb with time stamp
   3570  *   @get_memory : request memory ops table
   3571  *   @user       : user data ptr
   3572  *
   3573  * RETURN     : int32_t type of status
   3574  *              NO_ERROR  -- success
   3575  *              none-zero failure code
   3576  *==========================================================================*/
   3577 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
   3578                                             camera_data_callback data_cb,
   3579                                             camera_data_timestamp_callback data_cb_timestamp,
   3580                                             camera_request_memory get_memory,
   3581                                             void *user)
   3582 {
   3583     mNotifyCb        = notify_cb;
   3584     mDataCb          = data_cb;
   3585     mDataCbTimestamp = data_cb_timestamp;
   3586     mGetMemory       = get_memory;
   3587     mCallbackCookie  = user;
   3588     m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
   3589     return NO_ERROR;
   3590 }
   3591 
   3592 /*===========================================================================
   3593  * FUNCTION   : setJpegCallBacks
   3594  *
   3595  * DESCRIPTION: set JPEG callbacks impl
   3596  *
   3597  * PARAMETERS :
   3598  *   @jpegCb  : Jpeg callback method
   3599  *   @callbackCookie    : callback cookie
   3600  *
   3601  * RETURN     : int32_t type of status
   3602  *              NO_ERROR  -- success
   3603  *              none-zero failure code
   3604  *==========================================================================*/
   3605 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
   3606                                             void *callbackCookie)
   3607 {
   3608     LOGH("camera id %d", getCameraId());
   3609     mJpegCb        = jpegCb;
   3610     mJpegCallbackCookie  = callbackCookie;
   3611     m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
   3612 }
   3613 
   3614 /*===========================================================================
   3615  * FUNCTION   : enableMsgType
   3616  *
   3617  * DESCRIPTION: enable msg type impl
   3618  *
   3619  * PARAMETERS :
   3620  *   @msg_type  : msg type mask to be enabled
   3621  *
   3622  * RETURN     : int32_t type of status
   3623  *              NO_ERROR  -- success
   3624  *              none-zero failure code
   3625  *==========================================================================*/
   3626 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
   3627 {
   3628     int32_t rc = NO_ERROR;
   3629 
   3630     if (mParameters.isUBWCEnabled()) {
   3631         /*Need Special CALLBACK stream incase application requesting for
   3632               Preview callback  in UBWC case*/
   3633         if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
   3634                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
   3635             // Start callback channel only when preview/zsl channel is active
   3636             QCameraChannel* previewCh = NULL;
   3637             if (isZSLMode() && (getRecordingHintValue() != true)) {
   3638                 previewCh = m_channels[QCAMERA_CH_TYPE_ZSL];
   3639             } else {
   3640                 previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   3641             }
   3642             QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK];
   3643             if ((callbackCh != NULL) &&
   3644                     (previewCh != NULL) && previewCh->isActive()) {
   3645                 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
   3646                 if (rc != NO_ERROR) {
   3647                     LOGE("START Callback Channel failed");
   3648                 }
   3649             }
   3650         }
   3651     }
   3652     mMsgEnabled |= msg_type;
   3653     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
   3654     return rc;
   3655 }
   3656 
   3657 /*===========================================================================
   3658  * FUNCTION   : disableMsgType
   3659  *
   3660  * DESCRIPTION: disable msg type impl
   3661  *
   3662  * PARAMETERS :
   3663  *   @msg_type  : msg type mask to be disabled
   3664  *
   3665  * RETURN     : int32_t type of status
   3666  *              NO_ERROR  -- success
   3667  *              none-zero failure code
   3668  *==========================================================================*/
   3669 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
   3670 {
   3671     int32_t rc = NO_ERROR;
   3672 
   3673     if (mParameters.isUBWCEnabled()) {
   3674         /*STOP CALLBACK STREAM*/
   3675         if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
   3676                 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
   3677             // Stop callback channel only if it is active
   3678             if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) &&
   3679                    (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) {
   3680                 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
   3681                 if (rc != NO_ERROR) {
   3682                     LOGE("STOP Callback Channel failed");
   3683                 }
   3684             }
   3685         }
   3686     }
   3687     mMsgEnabled &= ~msg_type;
   3688     LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
   3689     return rc;
   3690 }
   3691 
   3692 /*===========================================================================
   3693  * FUNCTION   : msgTypeEnabled
   3694  *
   3695  * DESCRIPTION: impl to determine if certain msg_type is enabled
   3696  *
   3697  * PARAMETERS :
   3698  *   @msg_type  : msg type mask
   3699  *
   3700  * RETURN     : 0 -- not enabled
   3701  *              none 0 -- enabled
   3702  *==========================================================================*/
   3703 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
   3704 {
   3705     return (mMsgEnabled & msg_type);
   3706 }
   3707 
   3708 /*===========================================================================
   3709  * FUNCTION   : msgTypeEnabledWithLock
   3710  *
   3711  * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
   3712  *
   3713  * PARAMETERS :
   3714  *   @msg_type  : msg type mask
   3715  *
   3716  * RETURN     : 0 -- not enabled
   3717  *              none 0 -- enabled
   3718  *==========================================================================*/
   3719 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
   3720 {
   3721     int enabled = 0;
   3722     lockAPI();
   3723     enabled = mMsgEnabled & msg_type;
   3724     unlockAPI();
   3725     return enabled;
   3726 }
   3727 
   3728 /*===========================================================================
   3729  * FUNCTION   : startPreview
   3730  *
   3731  * DESCRIPTION: start preview impl
   3732  *
   3733  * PARAMETERS : none
   3734  *
   3735  * RETURN     : int32_t type of status
   3736  *              NO_ERROR  -- success
   3737  *              none-zero failure code
   3738  *==========================================================================*/
   3739 int QCamera2HardwareInterface::startPreview()
   3740 {
   3741     KPI_ATRACE_CALL();
   3742     int32_t rc = NO_ERROR;
   3743 
   3744     LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
   3745             mParameters.getRecordingHintValue());
   3746 
   3747     m_perfLock.lock_acq();
   3748 
   3749     updateThermalLevel((void *)&mThermalLevel);
   3750 
   3751     setDisplayFrameSkip();
   3752 
   3753     // start preview stream
   3754     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
   3755         rc = startChannel(QCAMERA_CH_TYPE_ZSL);
   3756     } else {
   3757         rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
   3758     }
   3759 
   3760     if (rc != NO_ERROR) {
   3761         LOGE("failed to start channels");
   3762         m_perfLock.lock_rel();
   3763         return rc;
   3764     }
   3765 
   3766     if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
   3767             && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
   3768         rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
   3769         if (rc != NO_ERROR) {
   3770             LOGE("failed to start callback stream");
   3771             stopChannel(QCAMERA_CH_TYPE_ZSL);
   3772             stopChannel(QCAMERA_CH_TYPE_PREVIEW);
   3773             m_perfLock.lock_rel();
   3774             return rc;
   3775         }
   3776     }
   3777 
   3778     updatePostPreviewParameters();
   3779     m_stateMachine.setPreviewCallbackNeeded(true);
   3780 
   3781     // if job id is non-zero, that means the postproc init job is already
   3782     // pending or complete
   3783     if (mInitPProcJob == 0) {
   3784         mInitPProcJob = deferPPInit();
   3785         if (mInitPProcJob == 0) {
   3786             LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
   3787                      mCameraHandle);
   3788             rc = -ENOMEM;
   3789             m_perfLock.lock_rel();
   3790             return rc;
   3791         }
   3792     }
   3793     m_perfLock.lock_rel();
   3794 
   3795     if (rc == NO_ERROR) {
   3796         // Set power Hint for preview
   3797         m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
   3798     }
   3799 
   3800     LOGI("X rc = %d", rc);
   3801     return rc;
   3802 }
   3803 
   3804 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
   3805     // Enable OIS only in Camera mode and 4k2k camcoder mode
   3806     int32_t rc = NO_ERROR;
   3807     rc = mParameters.updateOisValue(1);
   3808     return NO_ERROR;
   3809 }
   3810 
   3811 /*===========================================================================
   3812  * FUNCTION   : stopPreview
   3813  *
   3814  * DESCRIPTION: stop preview impl
   3815  *
   3816  * PARAMETERS : none
   3817  *
   3818  * RETURN     : int32_t type of status
   3819  *              NO_ERROR  -- success
   3820  *              none-zero failure code
   3821  *==========================================================================*/
   3822 int QCamera2HardwareInterface::stopPreview()
   3823 {
   3824     KPI_ATRACE_CALL();
   3825     LOGI("E");
   3826     mNumPreviewFaces = -1;
   3827     mActiveAF = false;
   3828 
   3829     // Disable power Hint for preview
   3830     m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
   3831 
   3832     m_perfLock.lock_acq();
   3833 
   3834     // stop preview stream
   3835     stopChannel(QCAMERA_CH_TYPE_CALLBACK);
   3836     stopChannel(QCAMERA_CH_TYPE_ZSL);
   3837     stopChannel(QCAMERA_CH_TYPE_PREVIEW);
   3838     stopChannel(QCAMERA_CH_TYPE_RAW);
   3839 
   3840     m_cbNotifier.flushPreviewNotifications();
   3841     //add for ts makeup
   3842 #ifdef TARGET_TS_MAKEUP
   3843     ts_makeup_finish();
   3844 #endif
   3845     // delete all channels from preparePreview
   3846     unpreparePreview();
   3847 
   3848     m_perfLock.lock_rel();
   3849 
   3850     LOGI("X");
   3851     return NO_ERROR;
   3852 }
   3853 
   3854 /*===========================================================================
   3855  * FUNCTION   : storeMetaDataInBuffers
   3856  *
   3857  * DESCRIPTION: enable store meta data in buffers for video frames impl
   3858  *
   3859  * PARAMETERS :
   3860  *   @enable  : flag if need enable
   3861  *
   3862  * RETURN     : int32_t type of status
   3863  *              NO_ERROR  -- success
   3864  *              none-zero failure code
   3865  *==========================================================================*/
   3866 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
   3867 {
   3868     mStoreMetaDataInFrame = enable;
   3869     return NO_ERROR;
   3870 }
   3871 
   3872 /*===========================================================================
   3873  * FUNCTION   : preStartRecording
   3874  *
   3875  * DESCRIPTION: Prepare start recording impl
   3876  *
   3877  * PARAMETERS : none
   3878  *
   3879  * RETURN     : int32_t type of status
   3880  *              NO_ERROR  -- success
   3881  *              none-zero failure code
   3882  *==========================================================================*/
   3883 int QCamera2HardwareInterface::preStartRecording()
   3884 {
   3885     int32_t rc = NO_ERROR;
   3886     LOGH("E");
   3887     if (mParameters.getRecordingHintValue() == false) {
   3888 
   3889         // Give HWI control to restart preview only in single camera mode.
   3890         // In dual-cam mode, this control belongs to muxer.
   3891         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   3892             LOGH("start recording when hint is false, stop preview first");
   3893             stopPreview();
   3894 
   3895             // Set recording hint to TRUE
   3896             mParameters.updateRecordingHintValue(TRUE);
   3897             rc = preparePreview();
   3898             if (rc == NO_ERROR) {
   3899                 rc = startPreview();
   3900             }
   3901         }
   3902         else
   3903         {
   3904             // For dual cam mode, update the flag mPreviewRestartNeeded to true
   3905             // Restart control will be handled by muxer.
   3906             mPreviewRestartNeeded = true;
   3907         }
   3908     }
   3909 
   3910     LOGH("X rc = %d", rc);
   3911     return rc;
   3912 }
   3913 
   3914 /*===========================================================================
   3915  * FUNCTION   : startRecording
   3916  *
   3917  * DESCRIPTION: start recording impl
   3918  *
   3919  * PARAMETERS : none
   3920  *
   3921  * RETURN     : int32_t type of status
   3922  *              NO_ERROR  -- success
   3923  *              none-zero failure code
   3924  *==========================================================================*/
   3925 int QCamera2HardwareInterface::startRecording()
   3926 {
   3927     int32_t rc = NO_ERROR;
   3928 
   3929     LOGI("E");
   3930     //link meta stream with video channel if low power mode.
   3931     if (isLowPowerMode()) {
   3932         // Find and try to link a metadata stream from preview channel
   3933         QCameraChannel *pMetaChannel = NULL;
   3934         QCameraStream *pMetaStream = NULL;
   3935         QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
   3936 
   3937         if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   3938             pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   3939             uint32_t streamNum = pMetaChannel->getNumOfStreams();
   3940             QCameraStream *pStream = NULL;
   3941             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   3942                 pStream = pMetaChannel->getStreamByIndex(i);
   3943                 if ((NULL != pStream) &&
   3944                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
   3945                     pMetaStream = pStream;
   3946                     break;
   3947                 }
   3948             }
   3949         }
   3950 
   3951         if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   3952             rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
   3953             if (NO_ERROR != rc) {
   3954                 LOGW("Metadata stream link failed %d", rc);
   3955             }
   3956         }
   3957     }
   3958 
   3959     if (rc == NO_ERROR) {
   3960         rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
   3961     }
   3962 
   3963     if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
   3964         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   3965         if (!mParameters.is4k2kVideoResolution()) {
   3966             // Find and try to link a metadata stream from preview channel
   3967             QCameraChannel *pMetaChannel = NULL;
   3968             QCameraStream *pMetaStream = NULL;
   3969 
   3970             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   3971                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   3972                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
   3973                 QCameraStream *pStream = NULL;
   3974                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   3975                     pStream = pMetaChannel->getStreamByIndex(i);
   3976                     if ((NULL != pStream) &&
   3977                             (CAM_STREAM_TYPE_METADATA ==
   3978                             pStream->getMyType())) {
   3979                         pMetaStream = pStream;
   3980                         break;
   3981                     }
   3982                 }
   3983             }
   3984 
   3985             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   3986                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   3987                 if (NO_ERROR != rc) {
   3988                     LOGW("Metadata stream link failed %d", rc);
   3989                 }
   3990             }
   3991         }
   3992         LOGH("START snapshot Channel for TNR processing");
   3993         rc = pChannel->start();
   3994     }
   3995 
   3996     if (rc == NO_ERROR) {
   3997         // Set power Hint for video encoding
   3998         m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
   3999     }
   4000 
   4001     LOGI("X rc = %d", rc);
   4002     return rc;
   4003 }
   4004 
   4005 /*===========================================================================
   4006  * FUNCTION   : stopRecording
   4007  *
   4008  * DESCRIPTION: stop recording impl
   4009  *
   4010  * PARAMETERS : none
   4011  *
   4012  * RETURN     : int32_t type of status
   4013  *              NO_ERROR  -- success
   4014  *              none-zero failure code
   4015  *==========================================================================*/
   4016 int QCamera2HardwareInterface::stopRecording()
   4017 {
   4018     LOGI("E");
   4019     // stop snapshot channel
   4020     if (mParameters.isTNRSnapshotEnabled()) {
   4021         LOGH("STOP snapshot Channel for TNR processing");
   4022         stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   4023     }
   4024     int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
   4025 
   4026     m_cbNotifier.flushVideoNotifications();
   4027     // Disable power hint for video encoding
   4028     m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
   4029     LOGI("X rc = %d", rc);
   4030     return rc;
   4031 }
   4032 
   4033 /*===========================================================================
   4034  * FUNCTION   : releaseRecordingFrame
   4035  *
   4036  * DESCRIPTION: return video frame impl
   4037  *
   4038  * PARAMETERS :
   4039  *   @opaque  : ptr to video frame to be returned
   4040  *
   4041  * RETURN     : int32_t type of status
   4042  *              NO_ERROR  -- success
   4043  *              none-zero failure code
   4044  *==========================================================================*/
   4045 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
   4046 {
   4047     int32_t rc = UNKNOWN_ERROR;
   4048     QCameraVideoChannel *pChannel =
   4049             (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
   4050     LOGD("opaque data = %p",opaque);
   4051 
   4052     if(pChannel != NULL) {
   4053         rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
   4054     }
   4055     return rc;
   4056 }
   4057 
   4058 /*===========================================================================
   4059  * FUNCTION   : autoFocus
   4060  *
   4061  * DESCRIPTION: start auto focus impl
   4062  *
   4063  * PARAMETERS : none
   4064  *
   4065  * RETURN     : int32_t type of status
   4066  *              NO_ERROR  -- success
   4067  *              none-zero failure code
   4068  *==========================================================================*/
   4069 int QCamera2HardwareInterface::autoFocus()
   4070 {
   4071     int rc = NO_ERROR;
   4072     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   4073     LOGH("E");
   4074 
   4075     switch (focusMode) {
   4076     case CAM_FOCUS_MODE_AUTO:
   4077     case CAM_FOCUS_MODE_MACRO:
   4078     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   4079     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   4080         mActiveAF = true;
   4081         LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
   4082                 focusMode, m_currentFocusState);
   4083         rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
   4084         break;
   4085     case CAM_FOCUS_MODE_INFINITY:
   4086     case CAM_FOCUS_MODE_FIXED:
   4087     case CAM_FOCUS_MODE_EDOF:
   4088     default:
   4089         LOGI("No ops in focusMode (%d)", focusMode);
   4090         rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
   4091         break;
   4092     }
   4093 
   4094     if (NO_ERROR != rc) {
   4095         mActiveAF = false;
   4096     }
   4097     LOGH("X rc = %d", rc);
   4098     return rc;
   4099 }
   4100 
   4101 /*===========================================================================
   4102  * FUNCTION   : cancelAutoFocus
   4103  *
   4104  * DESCRIPTION: cancel auto focus impl
   4105  *
   4106  * PARAMETERS : none
   4107  *
   4108  * RETURN     : int32_t type of status
   4109  *              NO_ERROR  -- success
   4110  *              none-zero failure code
   4111  *==========================================================================*/
   4112 int QCamera2HardwareInterface::cancelAutoFocus()
   4113 {
   4114     int rc = NO_ERROR;
   4115     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   4116 
   4117     switch (focusMode) {
   4118     case CAM_FOCUS_MODE_AUTO:
   4119     case CAM_FOCUS_MODE_MACRO:
   4120     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   4121     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   4122         mActiveAF = false;
   4123         rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
   4124         break;
   4125     case CAM_FOCUS_MODE_INFINITY:
   4126     case CAM_FOCUS_MODE_FIXED:
   4127     case CAM_FOCUS_MODE_EDOF:
   4128     default:
   4129         LOGD("No ops in focusMode (%d)", focusMode);
   4130         break;
   4131     }
   4132     return rc;
   4133 }
   4134 
   4135 /*===========================================================================
   4136  * FUNCTION   : processUFDumps
   4137  *
   4138  * DESCRIPTION: process UF jpeg dumps for refocus support
   4139  *
   4140  * PARAMETERS :
   4141  *   @evt     : payload of jpeg event, including information about jpeg encoding
   4142  *              status, jpeg size and so on.
   4143  *
   4144  * RETURN     : int32_t type of status
   4145  *              NO_ERROR  -- success
   4146  *              none-zero failure code
   4147  *
   4148  * NOTE       : none
   4149  *==========================================================================*/
   4150 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
   4151 {
   4152    bool ret = true;
   4153    if (mParameters.isUbiRefocus()) {
   4154        int index = (int)getOutputImageCount();
   4155        bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
   4156        char name[FILENAME_MAX];
   4157 
   4158        camera_memory_t *jpeg_mem = NULL;
   4159        omx_jpeg_ouput_buf_t *jpeg_out = NULL;
   4160        size_t dataLen;
   4161        uint8_t *dataPtr;
   4162        if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   4163            LOGE("Init PProc Deferred work failed");
   4164            return false;
   4165        }
   4166        if (!m_postprocessor.getJpegMemOpt()) {
   4167            dataLen = evt->out_data.buf_filled_len;
   4168            dataPtr = evt->out_data.buf_vaddr;
   4169        } else {
   4170            jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
   4171            if (!jpeg_out) {
   4172               LOGE("Null pointer detected");
   4173               return false;
   4174            }
   4175            jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
   4176            if (!jpeg_mem) {
   4177               LOGE("Null pointer detected");
   4178               return false;
   4179            }
   4180            dataPtr = (uint8_t *)jpeg_mem->data;
   4181            dataLen = jpeg_mem->size;
   4182        }
   4183 
   4184        if (allFocusImage)  {
   4185            snprintf(name, sizeof(name), "AllFocusImage");
   4186            index = -1;
   4187        } else {
   4188            snprintf(name, sizeof(name), "%d", 0);
   4189        }
   4190        CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
   4191            dataPtr, dataLen);
   4192        LOGD("Dump the image %d %d allFocusImage %d",
   4193            getOutputImageCount(), index, allFocusImage);
   4194        setOutputImageCount(getOutputImageCount() + 1);
   4195        if (!allFocusImage) {
   4196            ret = false;
   4197        }
   4198    }
   4199    return ret;
   4200 }
   4201 
   4202 /*===========================================================================
   4203  * FUNCTION   : unconfigureAdvancedCapture
   4204  *
   4205  * DESCRIPTION: unconfigure Advanced Capture.
   4206  *
   4207  * PARAMETERS : none
   4208  *
   4209  * RETURN     : int32_t type of status
   4210  *              NO_ERROR  -- success
   4211  *              none-zero failure code
   4212  *==========================================================================*/
   4213 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
   4214 {
   4215     int32_t rc = NO_ERROR;
   4216 
   4217     /*Disable Quadra CFA mode*/
   4218     LOGH("Disabling Quadra CFA mode");
   4219     mParameters.setQuadraCfaMode(false, true);
   4220 
   4221     if (mAdvancedCaptureConfigured) {
   4222 
   4223         mAdvancedCaptureConfigured = false;
   4224 
   4225         if(mIs3ALocked) {
   4226             mParameters.set3ALock(false);
   4227             mIs3ALocked = false;
   4228         }
   4229         if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
   4230             rc = mParameters.setToneMapMode(true, true);
   4231             if (rc != NO_ERROR) {
   4232                 LOGW("Failed to enable tone map during HDR/AEBracketing");
   4233             }
   4234             mHDRBracketingEnabled = false;
   4235             rc = mParameters.stopAEBracket();
   4236         } else if ((mParameters.isChromaFlashEnabled())
   4237                 || (mFlashConfigured && !mLongshotEnabled)
   4238                 || (mLowLightConfigured == true)
   4239                 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4240             rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured);
   4241         } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4242             rc = configureAFBracketing(false);
   4243         } else if (mParameters.isOptiZoomEnabled()) {
   4244             rc = mParameters.setAndCommitZoom(mZoomLevel);
   4245             setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
   4246         } else if (mParameters.isStillMoreEnabled()) {
   4247             cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
   4248             stillmore_config.burst_count = 0;
   4249             mParameters.setStillMoreSettings(stillmore_config);
   4250 
   4251             /* If SeeMore is running, it will handle re-enabling tone map */
   4252             if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
   4253                 rc = mParameters.setToneMapMode(true, true);
   4254                 if (rc != NO_ERROR) {
   4255                     LOGW("Failed to enable tone map during StillMore");
   4256                 }
   4257             }
   4258 
   4259             /* Re-enable Tintless */
   4260             mParameters.setTintless(true);
   4261         } else {
   4262             LOGW("No Advanced Capture feature enabled!!");
   4263             rc = BAD_VALUE;
   4264         }
   4265     }
   4266 
   4267     return rc;
   4268 }
   4269 
   4270 /*===========================================================================
   4271  * FUNCTION   : configureAdvancedCapture
   4272  *
   4273  * DESCRIPTION: configure Advanced Capture.
   4274  *
   4275  * PARAMETERS : none
   4276  *
   4277  * RETURN     : int32_t type of status
   4278  *              NO_ERROR  -- success
   4279  *              none-zero failure code
   4280  *==========================================================================*/
   4281 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
   4282 {
   4283     LOGH("E");
   4284     int32_t rc = NO_ERROR;
   4285 
   4286     rc = mParameters.checkFeatureConcurrency();
   4287     if (rc != NO_ERROR) {
   4288         LOGE("Cannot support Advanced capture modes");
   4289         return rc;
   4290     }
   4291     /*Enable Quadra CFA mode*/
   4292     LOGH("Enabling Quadra CFA mode");
   4293     mParameters.setQuadraCfaMode(true, true);
   4294 
   4295     setOutputImageCount(0);
   4296     mInputCount = 0;
   4297     mAdvancedCaptureConfigured = true;
   4298     /* Display should be disabled for advanced modes */
   4299     bool bSkipDisplay = true;
   4300 
   4301     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
   4302         // no Advance capture settings for Aux camera
   4303         LOGH("X Secondary Camera, no need to process!! ");
   4304         return rc;
   4305     }
   4306 
   4307     /* Do not stop display if in stillmore livesnapshot */
   4308     if (mParameters.isStillMoreEnabled() &&
   4309             mParameters.isSeeMoreEnabled()) {
   4310         bSkipDisplay = false;
   4311     }
   4312     if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4313         rc = configureAFBracketing();
   4314     } else if (mParameters.isOptiZoomEnabled()) {
   4315         rc = configureOptiZoom();
   4316     } else if(mParameters.isHDREnabled()) {
   4317         rc = configureHDRBracketing();
   4318         if (mHDRBracketingEnabled) {
   4319             rc = mParameters.setToneMapMode(false, true);
   4320             if (rc != NO_ERROR) {
   4321                 LOGW("Failed to disable tone map during HDR");
   4322             }
   4323         }
   4324     } else if (mParameters.isAEBracketEnabled()) {
   4325         rc = mParameters.setToneMapMode(false, true);
   4326         if (rc != NO_ERROR) {
   4327             LOGW("Failed to disable tone map during AEBracketing");
   4328         }
   4329         rc = configureAEBracketing();
   4330     } else if (mParameters.isStillMoreEnabled()) {
   4331         bSkipDisplay = false;
   4332         rc = configureStillMore();
   4333     } else if ((mParameters.isChromaFlashEnabled())
   4334             || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
   4335             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4336         rc = mParameters.configFrameCapture(TRUE);
   4337         if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) {
   4338             mLowLightConfigured = true;
   4339         }
   4340     } else if (mFlashNeeded && !mLongshotEnabled) {
   4341         rc = mParameters.configFrameCapture(TRUE);
   4342         mFlashConfigured = true;
   4343         bSkipDisplay = false;
   4344     } else {
   4345         LOGH("Advanced Capture feature not enabled!! ");
   4346         mAdvancedCaptureConfigured = false;
   4347         bSkipDisplay = false;
   4348     }
   4349 
   4350     LOGH("Stop preview temporarily for advanced captures");
   4351     setDisplaySkip(bSkipDisplay);
   4352 
   4353     LOGH("X rc = %d", rc);
   4354     return rc;
   4355 }
   4356 
   4357 /*===========================================================================
   4358  * FUNCTION   : configureAFBracketing
   4359  *
   4360  * DESCRIPTION: configure AF Bracketing.
   4361  *
   4362  * PARAMETERS : none
   4363  *
   4364  * RETURN     : int32_t type of status
   4365  *              NO_ERROR  -- success
   4366  *              none-zero failure code
   4367  *==========================================================================*/
   4368 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
   4369 {
   4370     LOGH("E");
   4371     int32_t rc = NO_ERROR;
   4372     cam_af_bracketing_t *af_bracketing_need;
   4373 
   4374     if (mParameters.isUbiRefocus()) {
   4375         af_bracketing_need =
   4376                 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
   4377     } else {
   4378         af_bracketing_need =
   4379                 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
   4380     }
   4381 
   4382     //Enable AF Bracketing.
   4383     cam_af_bracketing_t afBracket;
   4384     memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
   4385     afBracket.enable = enable;
   4386     afBracket.burst_count = af_bracketing_need->burst_count;
   4387 
   4388     for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
   4389         afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
   4390         LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
   4391     }
   4392     //Send cmd to backend to set AF Bracketing for Ubi Focus.
   4393     rc = mParameters.commitAFBracket(afBracket);
   4394     if ( NO_ERROR != rc ) {
   4395         LOGE("cannot configure AF bracketing");
   4396         return rc;
   4397     }
   4398     if (enable) {
   4399         mParameters.set3ALock(true);
   4400         mIs3ALocked = true;
   4401     }
   4402     LOGH("X rc = %d", rc);
   4403     return rc;
   4404 }
   4405 
   4406 /*===========================================================================
   4407  * FUNCTION   : configureHDRBracketing
   4408  *
   4409  * DESCRIPTION: configure HDR Bracketing.
   4410  *
   4411  * PARAMETERS : none
   4412  *
   4413  * RETURN     : int32_t type of status
   4414  *              NO_ERROR  -- success
   4415  *              none-zero failure code
   4416  *==========================================================================*/
   4417 int32_t QCamera2HardwareInterface::configureHDRBracketing()
   4418 {
   4419     LOGH("E");
   4420     int32_t rc = NO_ERROR;
   4421 
   4422     cam_hdr_bracketing_info_t& hdrBracketingSetting =
   4423             gCamCapability[mCameraId]->hdr_bracketing_setting;
   4424 
   4425     // 'values' should be in "idx1,idx2,idx3,..." format
   4426     uint32_t hdrFrameCount =
   4427             hdrBracketingSetting.num_frames;
   4428     LOGH("HDR values %d, %d frame count: %u",
   4429           (int8_t) hdrBracketingSetting.exp_val.values[0],
   4430           (int8_t) hdrBracketingSetting.exp_val.values[1],
   4431           hdrFrameCount);
   4432 
   4433     // Enable AE Bracketing for HDR
   4434     cam_exp_bracketing_t aeBracket;
   4435     memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
   4436     aeBracket.mode =
   4437         hdrBracketingSetting.exp_val.mode;
   4438 
   4439     if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
   4440         mHDRBracketingEnabled = true;
   4441     }
   4442 
   4443     String8 tmp;
   4444     for (uint32_t i = 0; i < hdrFrameCount; i++) {
   4445         tmp.appendFormat("%d",
   4446             (int8_t) hdrBracketingSetting.exp_val.values[i]);
   4447         tmp.append(",");
   4448     }
   4449     if (mParameters.isHDR1xFrameEnabled()
   4450         && mParameters.isHDR1xExtraBufferNeeded()) {
   4451             tmp.appendFormat("%d", 0);
   4452             tmp.append(",");
   4453     }
   4454 
   4455     if( !tmp.isEmpty() &&
   4456         ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
   4457         //Trim last comma
   4458         memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
   4459         memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
   4460     }
   4461 
   4462     LOGH("HDR config values %s",
   4463           aeBracket.values);
   4464     rc = mParameters.setHDRAEBracket(aeBracket);
   4465     if ( NO_ERROR != rc ) {
   4466         LOGE("cannot configure HDR bracketing");
   4467         return rc;
   4468     }
   4469     LOGH("X rc = %d", rc);
   4470     return rc;
   4471 }
   4472 
   4473 /*===========================================================================
   4474  * FUNCTION   : configureAEBracketing
   4475  *
   4476  * DESCRIPTION: configure AE Bracketing.
   4477  *
   4478  * PARAMETERS : none
   4479  *
   4480  * RETURN     : int32_t type of status
   4481  *              NO_ERROR  -- success
   4482  *              none-zero failure code
   4483  *==========================================================================*/
   4484 int32_t QCamera2HardwareInterface::configureAEBracketing()
   4485 {
   4486     LOGH("E");
   4487     int32_t rc = NO_ERROR;
   4488 
   4489     rc = mParameters.setAEBracketing();
   4490     if ( NO_ERROR != rc ) {
   4491         LOGE("cannot configure AE bracketing");
   4492         return rc;
   4493     }
   4494     LOGH("X rc = %d", rc);
   4495     return rc;
   4496 }
   4497 
   4498 /*===========================================================================
   4499  * FUNCTION   : configureOptiZoom
   4500  *
   4501  * DESCRIPTION: configure Opti Zoom.
   4502  *
   4503  * PARAMETERS : none
   4504  *
   4505  * RETURN     : int32_t type of status
   4506  *              NO_ERROR  -- success
   4507  *              none-zero failure code
   4508  *==========================================================================*/
   4509 int32_t QCamera2HardwareInterface::configureOptiZoom()
   4510 {
   4511     int32_t rc = NO_ERROR;
   4512 
   4513     //store current zoom level.
   4514     mZoomLevel = mParameters.getParmZoomLevel();
   4515 
   4516     //set zoom level to 1x;
   4517     mParameters.setAndCommitZoom(0);
   4518 
   4519     mParameters.set3ALock(true);
   4520     mIs3ALocked = true;
   4521 
   4522     return rc;
   4523 }
   4524 
   4525 /*===========================================================================
   4526  * FUNCTION   : configureStillMore
   4527  *
   4528  * DESCRIPTION: configure StillMore.
   4529  *
   4530  * PARAMETERS : none
   4531  *
   4532  * RETURN     : int32_t type of status
   4533  *              NO_ERROR  -- success
   4534  *              none-zero failure code
   4535  *==========================================================================*/
   4536 int32_t QCamera2HardwareInterface::configureStillMore()
   4537 {
   4538     int32_t rc = NO_ERROR;
   4539     uint8_t burst_cnt = 0;
   4540     cam_still_more_t stillmore_config;
   4541     cam_still_more_t stillmore_cap;
   4542 
   4543     /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
   4544     if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
   4545         rc = mParameters.setToneMapMode(false, true);
   4546         if (rc != NO_ERROR) {
   4547             LOGW("Failed to disable tone map during StillMore");
   4548         }
   4549     }
   4550 
   4551     /* Lock 3A */
   4552     mParameters.set3ALock(true);
   4553     mIs3ALocked = true;
   4554 
   4555     /* Disable Tintless */
   4556     mParameters.setTintless(false);
   4557 
   4558     /* Initialize burst count from capability */
   4559     stillmore_cap = mParameters.getStillMoreCapability();
   4560     burst_cnt = stillmore_cap.max_burst_count;
   4561 
   4562     /* Reconfigure burst count from dynamic scene data */
   4563     cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
   4564     if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
   4565             dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
   4566         burst_cnt = dynamic_img_data.input_count;
   4567     }
   4568 
   4569     /* Reconfigure burst count in the case of liveshot */
   4570     if (mParameters.isSeeMoreEnabled()) {
   4571         burst_cnt = 1;
   4572     }
   4573 
   4574     /* Reconfigure burst count from user input */
   4575     char prop[PROPERTY_VALUE_MAX];
   4576     property_get("persist.camera.imglib.stillmore", prop, "0");
   4577     uint8_t burst_setprop = (uint32_t)atoi(prop);
   4578     if (burst_setprop != 0)  {
   4579        if ((burst_setprop < stillmore_cap.min_burst_count) ||
   4580                (burst_setprop > stillmore_cap.max_burst_count)) {
   4581            burst_cnt = stillmore_cap.max_burst_count;
   4582        } else {
   4583            burst_cnt = burst_setprop;
   4584        }
   4585     }
   4586 
   4587     memset(&stillmore_config, 0, sizeof(cam_still_more_t));
   4588     stillmore_config.burst_count = burst_cnt;
   4589     mParameters.setStillMoreSettings(stillmore_config);
   4590 
   4591     LOGH("Stillmore burst %d", burst_cnt);
   4592 
   4593     return rc;
   4594 }
   4595 
   4596 /*===========================================================================
   4597  * FUNCTION   : stopAdvancedCapture
   4598  *
   4599  * DESCRIPTION: stops advanced capture based on capture type
   4600  *
   4601  * PARAMETERS :
   4602  *   @pChannel : channel.
   4603  *
   4604  * RETURN     : int32_t type of status
   4605  *              NO_ERROR  -- success
   4606  *              none-zero failure code
   4607  *==========================================================================*/
   4608 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
   4609         QCameraPicChannel *pChannel)
   4610 {
   4611     LOGH("stop bracketig");
   4612     int32_t rc = NO_ERROR;
   4613 
   4614     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4615         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
   4616     } else if (mParameters.isChromaFlashEnabled()
   4617             || (mFlashConfigured && !mLongshotEnabled)
   4618             || (mLowLightConfigured == true)
   4619             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4620         rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
   4621         mFlashConfigured = false;
   4622         mLowLightConfigured = false;
   4623     } else if(mParameters.isHDREnabled()
   4624             || mParameters.isAEBracketEnabled()) {
   4625         rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
   4626     } else if (mParameters.isOptiZoomEnabled()) {
   4627         rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
   4628     } else if (mParameters.isStillMoreEnabled()) {
   4629         LOGH("stopAdvancedCapture not needed for StillMore");
   4630     } else {
   4631         LOGH("No Advanced Capture feature enabled!");
   4632         rc = BAD_VALUE;
   4633     }
   4634     return rc;
   4635 }
   4636 
   4637 /*===========================================================================
   4638  * FUNCTION   : startAdvancedCapture
   4639  *
   4640  * DESCRIPTION: starts advanced capture based on capture type
   4641  *
   4642  * PARAMETERS :
   4643  *   @pChannel : channel.
   4644  *
   4645  * RETURN     : int32_t type of status
   4646  *              NO_ERROR  -- success
   4647  *              none-zero failure code
   4648  *==========================================================================*/
   4649 int32_t QCamera2HardwareInterface::startAdvancedCapture(
   4650         QCameraPicChannel *pChannel)
   4651 {
   4652     LOGH("Start bracketing");
   4653     int32_t rc = NO_ERROR;
   4654 
   4655     if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
   4656         rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
   4657     } else if (mParameters.isOptiZoomEnabled()) {
   4658         rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
   4659     } else if (mParameters.isStillMoreEnabled()) {
   4660         LOGH("startAdvancedCapture not needed for StillMore");
   4661     } else if (mParameters.isHDREnabled()
   4662             || mParameters.isAEBracketEnabled()) {
   4663         rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
   4664     } else if (mParameters.isChromaFlashEnabled()
   4665             || (mFlashNeeded && !mLongshotEnabled)
   4666             || (mLowLightConfigured == true)
   4667             || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
   4668         cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
   4669         rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
   4670     } else {
   4671         LOGE("No Advanced Capture feature enabled!");
   4672         rc = BAD_VALUE;
   4673     }
   4674     return rc;
   4675 }
   4676 
   4677 /*===========================================================================
   4678  * FUNCTION   : preTakePicture
   4679  *
   4680  * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
   4681  *
   4682  * PARAMETERS : none
   4683  *
   4684  * RETURN     : int32_t type of status
   4685  *              NO_ERROR  -- success
   4686  *              none-zero failure code
   4687  *==========================================================================*/
   4688 int QCamera2HardwareInterface::preTakePicture()
   4689 {
   4690     int32_t rc = NO_ERROR;
   4691     LOGH("E");
   4692     if (mParameters.getRecordingHintValue() == true) {
   4693 
   4694         // Give HWI control to restart preview only in single camera mode.
   4695         // In dual-cam mode, this control belongs to muxer.
   4696         if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
   4697             LOGH("restart preview if rec hint is true and preview is running");
   4698             stopPreview();
   4699             mParameters.updateRecordingHintValue(FALSE);
   4700             // start preview again
   4701             rc = preparePreview();
   4702             if (rc == NO_ERROR) {
   4703                 rc = startPreview();
   4704                 if (rc != NO_ERROR) {
   4705                     unpreparePreview();
   4706                 }
   4707             }
   4708         }
   4709         else
   4710         {
   4711             // For dual cam mode, update the flag mPreviewRestartNeeded to true
   4712             // Restart control will be handled by muxer.
   4713             mPreviewRestartNeeded = true;
   4714         }
   4715     }
   4716 
   4717     LOGH("X rc = %d", rc);
   4718     return rc;
   4719 }
   4720 
   4721 /*===========================================================================
   4722  * FUNCTION   : takePicture
   4723  *
   4724  * DESCRIPTION: take picture impl
   4725  *
   4726  * PARAMETERS : none
   4727  *
   4728  * RETURN     : int32_t type of status
   4729  *              NO_ERROR  -- success
   4730  *              none-zero failure code
   4731  *==========================================================================*/
   4732 int QCamera2HardwareInterface::takePicture()
   4733 {
   4734     int rc = NO_ERROR;
   4735 
   4736     // Get total number for snapshots (retro + regular)
   4737     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
   4738     // Get number of retro-active snapshots
   4739     uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
   4740     LOGH("E");
   4741 
   4742     //Set rotation value from user settings as Jpeg rotation
   4743     //to configure back-end modules.
   4744     mParameters.setJpegRotation(mParameters.getRotation());
   4745 
   4746     // Check if retro-active snapshots are not enabled
   4747     if (!isRetroPicture() || !mParameters.isZSLMode()) {
   4748       numRetroSnapshots = 0;
   4749       LOGH("Reset retro snaphot count to zero");
   4750     }
   4751 
   4752     //Do special configure for advanced capture modes.
   4753     rc = configureAdvancedCapture();
   4754     if (rc != NO_ERROR) {
   4755         LOGE("Unsupported capture call");
   4756         return rc;
   4757     }
   4758 
   4759 #ifdef DUAL_CAM_TEST //Temporary macro. Added to simulate B+B snapshot. Will be removed
   4760     if(mActiveCamera == (MM_CAMERA_TYPE_MAIN | MM_CAMERA_TYPE_AUX)) {
   4761         numSnapshots = 1;
   4762     }
   4763 #endif
   4764 
   4765     if (mAdvancedCaptureConfigured) {
   4766         numSnapshots = mParameters.getBurstCountForAdvancedCapture();
   4767     }
   4768     LOGI("snap count = %d zsl = %d advanced = %d",
   4769             numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured);
   4770 
   4771     if (mParameters.isZSLMode()) {
   4772         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   4773         QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
   4774         if (NULL != pPicChannel) {
   4775 
   4776             if (mParameters.getofflineRAW()) {
   4777                 startRAWChannel(pPicChannel);
   4778                 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
   4779                 if (pPicChannel == NULL) {
   4780                     LOGE("RAW Channel is NULL in Manual capture mode");
   4781                     stopRAWChannel();
   4782                     return UNKNOWN_ERROR;
   4783                 }
   4784             }
   4785 
   4786             rc = configureOnlineRotation(*pPicChannel);
   4787             if (rc != NO_ERROR) {
   4788                 LOGE("online rotation failed");
   4789                 return rc;
   4790             }
   4791 
   4792             // start postprocessor
   4793             DeferWorkArgs args;
   4794             memset(&args, 0, sizeof(DeferWorkArgs));
   4795 
   4796             args.pprocArgs = pPicChannel;
   4797 
   4798             // No need to wait for mInitPProcJob here, because it was
   4799             // queued in startPreview, and will definitely be processed before
   4800             // mReprocJob can begin.
   4801             mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   4802                     args);
   4803             if (mReprocJob == 0) {
   4804                 LOGE("Failure: Unable to start pproc");
   4805                 return -ENOMEM;
   4806             }
   4807 
   4808             // Check if all preview buffers are mapped before creating
   4809             // a jpeg session as preview stream buffers are queried during the same
   4810             uint8_t numStreams = pChannel->getNumOfStreams();
   4811             QCameraStream *pStream = NULL;
   4812             QCameraStream *pPreviewStream = NULL;
   4813             for (uint8_t i = 0 ; i < numStreams ; i++ ) {
   4814                 pStream = pChannel->getStreamByIndex(i);
   4815                 if (!pStream)
   4816                     continue;
   4817                 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
   4818                     pPreviewStream = pStream;
   4819                     break;
   4820                 }
   4821             }
   4822             if (pPreviewStream != NULL) {
   4823                 Mutex::Autolock l(mMapLock);
   4824                 QCameraMemory *pMemory = pStream->getStreamBufs();
   4825                 if (!pMemory) {
   4826                     LOGE("Error!! pMemory is NULL");
   4827                     return -ENOMEM;
   4828                 }
   4829 
   4830                 uint8_t waitCnt = 2;
   4831                 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
   4832                     LOGL(" Waiting for preview buffers to be mapped");
   4833                     mMapCond.waitRelative(
   4834                             mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
   4835                     LOGL("Wait completed!!");
   4836                     waitCnt--;
   4837                 }
   4838                 // If all buffers are not mapped after retries, assert
   4839                 assert(pMemory->checkIfAllBuffersMapped());
   4840             } else {
   4841                 assert(pPreviewStream);
   4842             }
   4843 
   4844             // Create JPEG session
   4845             mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   4846                     args);
   4847             if (mJpegJob == 0) {
   4848                 LOGE("Failed to queue CREATE_JPEG_SESSION");
   4849                 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4850                         LOGE("Reprocess Deferred work was failed");
   4851                 }
   4852                 m_postprocessor.stop();
   4853                 return -ENOMEM;
   4854             }
   4855 
   4856             if (mAdvancedCaptureConfigured) {
   4857                 rc = startAdvancedCapture(pPicChannel);
   4858                 if (rc != NO_ERROR) {
   4859                     LOGE("cannot start zsl advanced capture");
   4860                     return rc;
   4861                 }
   4862             }
   4863             if (mLongshotEnabled && mPrepSnapRun) {
   4864                 mCameraHandle->ops->start_zsl_snapshot(
   4865                         mCameraHandle->camera_handle,
   4866                         pPicChannel->getMyHandle());
   4867             }
   4868             // If frame sync is ON and it is a SECONDARY camera,
   4869             // we do not need to send the take picture command to interface
   4870             // It will be handled along with PRIMARY camera takePicture request
   4871             mm_camera_req_buf_t buf;
   4872             memset(&buf, 0x0, sizeof(buf));
   4873             if ((!mParameters.isAdvCamFeaturesEnabled() &&
   4874                     !mFlashNeeded &&
   4875                     !isLongshotEnabled() &&
   4876                     isFrameSyncEnabled()) &&
   4877                     (getRelatedCamSyncInfo()->sync_control ==
   4878                     CAM_SYNC_RELATED_SENSORS_ON)) {
   4879                 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
   4880                     buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
   4881                     buf.num_buf_requested = numSnapshots;
   4882                     rc = pPicChannel->takePicture(&buf);
   4883                     if (rc != NO_ERROR) {
   4884                         LOGE("FS_DBG cannot take ZSL picture, stop pproc");
   4885                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4886                             LOGE("Reprocess Deferred work failed");
   4887                             return UNKNOWN_ERROR;
   4888                         }
   4889                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   4890                             LOGE("Jpeg Deferred work failed");
   4891                             return UNKNOWN_ERROR;
   4892                         }
   4893                         m_postprocessor.stop();
   4894                         return rc;
   4895                     }
   4896                     LOGI("PRIMARY camera: send frame sync takePicture!!");
   4897                 }
   4898             } else {
   4899                 buf.type = MM_CAMERA_REQ_SUPER_BUF;
   4900                 buf.num_buf_requested = numSnapshots;
   4901                 buf.num_retro_buf_requested = numRetroSnapshots;
   4902                 rc = pPicChannel->takePicture(&buf);
   4903                 if (rc != NO_ERROR) {
   4904                     LOGE("cannot take ZSL picture, stop pproc");
   4905                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4906                             LOGE("Reprocess Deferred work failed");
   4907                             return UNKNOWN_ERROR;
   4908                         }
   4909                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   4910                             LOGE("Jpeg Deferred work failed");
   4911                             return UNKNOWN_ERROR;
   4912                         }
   4913                     m_postprocessor.stop();
   4914                     return rc;
   4915                 }
   4916             }
   4917         } else {
   4918             LOGE("ZSL channel is NULL");
   4919             return UNKNOWN_ERROR;
   4920         }
   4921     } else {
   4922 
   4923         // start snapshot
   4924         if (mParameters.isJpegPictureFormat() ||
   4925                 mParameters.isNV16PictureFormat() ||
   4926                 mParameters.isNV21PictureFormat()) {
   4927 
   4928             //STOP Preview for Non ZSL use case
   4929             stopPreview();
   4930 
   4931             //Config CAPTURE channels
   4932             rc = declareSnapshotStreams();
   4933             if (NO_ERROR != rc) {
   4934                 return rc;
   4935             }
   4936 
   4937             rc = addCaptureChannel();
   4938             if ((rc == NO_ERROR) &&
   4939                     (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
   4940 
   4941                 if (!mParameters.getofflineRAW()) {
   4942                     rc = configureOnlineRotation(
   4943                         *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
   4944                     if (rc != NO_ERROR) {
   4945                         LOGE("online rotation failed");
   4946                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
   4947                         return rc;
   4948                     }
   4949                 }
   4950 
   4951                 DeferWorkArgs args;
   4952                 memset(&args, 0, sizeof(DeferWorkArgs));
   4953 
   4954                 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
   4955 
   4956                 // No need to wait for mInitPProcJob here, because it was
   4957                 // queued in startPreview, and will definitely be processed before
   4958                 // mReprocJob can begin.
   4959                 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   4960                         args);
   4961                 if (mReprocJob == 0) {
   4962                     LOGE("Failure: Unable to start pproc");
   4963                     return -ENOMEM;
   4964                 }
   4965 
   4966                 // Create JPEG session
   4967                 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   4968                         args);
   4969                 if (mJpegJob == 0) {
   4970                     LOGE("Failed to queue CREATE_JPEG_SESSION");
   4971                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4972                         LOGE("Reprocess Deferred work was failed");
   4973                     }
   4974                     m_postprocessor.stop();
   4975                     return -ENOMEM;
   4976                 }
   4977 
   4978                 // start catpure channel
   4979                 rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
   4980                 if (rc != NO_ERROR) {
   4981                     LOGE("cannot start capture channel");
   4982                     if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   4983                         LOGE("Reprocess Deferred work failed");
   4984                         return UNKNOWN_ERROR;
   4985                     }
   4986                     if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   4987                         LOGE("Jpeg Deferred work failed");
   4988                         return UNKNOWN_ERROR;
   4989                     }
   4990                     delChannel(QCAMERA_CH_TYPE_CAPTURE);
   4991                     return rc;
   4992                 }
   4993 
   4994                 QCameraPicChannel *pCapChannel =
   4995                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
   4996                 if (NULL != pCapChannel) {
   4997                     if (mParameters.isUbiFocusEnabled() ||
   4998                             mParameters.isUbiRefocus() ||
   4999                             mParameters.isChromaFlashEnabled()) {
   5000                         rc = startAdvancedCapture(pCapChannel);
   5001                         if (rc != NO_ERROR) {
   5002                             LOGE("cannot start advanced capture");
   5003                             return rc;
   5004                         }
   5005                     }
   5006                 }
   5007                 if ( mLongshotEnabled ) {
   5008                     rc = longShot();
   5009                     if (NO_ERROR != rc) {
   5010                         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5011                             LOGE("Reprocess Deferred work failed");
   5012                             return UNKNOWN_ERROR;
   5013                         }
   5014                         if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   5015                             LOGE("Jpeg Deferred work failed");
   5016                             return UNKNOWN_ERROR;
   5017                         }
   5018                         delChannel(QCAMERA_CH_TYPE_CAPTURE);
   5019                         return rc;
   5020                     }
   5021                 }
   5022             } else {
   5023                 LOGE("cannot add capture channel");
   5024                 delChannel(QCAMERA_CH_TYPE_CAPTURE);
   5025                 return rc;
   5026             }
   5027         } else {
   5028             // Stop Preview before taking NZSL snapshot
   5029             stopPreview();
   5030 
   5031             rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
   5032             if (NO_ERROR != rc) {
   5033                 LOGE("Raw dimension update failed %d", rc);
   5034                 return rc;
   5035             }
   5036 
   5037             rc = declareSnapshotStreams();
   5038             if (NO_ERROR != rc) {
   5039                 LOGE("RAW stream info configuration failed %d", rc);
   5040                 return rc;
   5041             }
   5042 
   5043             rc = addChannel(QCAMERA_CH_TYPE_RAW);
   5044             if (rc == NO_ERROR) {
   5045                 // start postprocessor
   5046                 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   5047                     LOGE("Reprocess Deferred work failed");
   5048                     return UNKNOWN_ERROR;
   5049                 }
   5050 
   5051                 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
   5052                 if (rc != NO_ERROR) {
   5053                     LOGE("cannot start postprocessor");
   5054                     delChannel(QCAMERA_CH_TYPE_RAW);
   5055                     return rc;
   5056                 }
   5057 
   5058                 rc = startChannel(QCAMERA_CH_TYPE_RAW);
   5059                 if (rc != NO_ERROR) {
   5060                     LOGE("cannot start raw channel");
   5061                     m_postprocessor.stop();
   5062                     delChannel(QCAMERA_CH_TYPE_RAW);
   5063                     return rc;
   5064                 }
   5065             } else {
   5066                 LOGE("cannot add raw channel");
   5067                 return rc;
   5068             }
   5069         }
   5070     }
   5071 
   5072     //When take picture, stop sending preview callbacks to APP
   5073     m_stateMachine.setPreviewCallbackNeeded(false);
   5074     LOGI("X rc = %d", rc);
   5075     return rc;
   5076 }
   5077 
   5078 /*===========================================================================
   5079  * FUNCTION   : configureOnlineRotation
   5080  *
   5081  * DESCRIPTION: Configure backend with expected rotation for snapshot stream
   5082  *
   5083  * PARAMETERS :
   5084  *    @ch     : Channel containing a snapshot stream
   5085  *
   5086  * RETURN     : int32_t type of status
   5087  *              NO_ERROR  -- success
   5088  *              none-zero failure code
   5089  *==========================================================================*/
   5090 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
   5091 {
   5092     int rc = NO_ERROR;
   5093     uint32_t streamId = 0;
   5094     QCameraStream *pStream = NULL;
   5095 
   5096     for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
   5097         QCameraStream *stream = ch.getStreamByIndex(i);
   5098         if ((NULL != stream) &&
   5099                 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
   5100                 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
   5101             pStream = stream;
   5102             break;
   5103         }
   5104     }
   5105 
   5106     if (NULL == pStream) {
   5107         LOGE("No snapshot stream found!");
   5108         return BAD_VALUE;
   5109     }
   5110 
   5111     streamId = pStream->getMyServerID();
   5112     // Update online rotation configuration
   5113     rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
   5114             mParameters.getDeviceRotation());
   5115     if (rc != NO_ERROR) {
   5116         LOGE("addOnlineRotation failed %d", rc);
   5117         return rc;
   5118     }
   5119 
   5120     return rc;
   5121 }
   5122 
   5123 /*===========================================================================
   5124  * FUNCTION   : declareSnapshotStreams
   5125  *
   5126  * DESCRIPTION: Configure backend with expected snapshot streams
   5127  *
   5128  * PARAMETERS : none
   5129  *
   5130  * RETURN     : int32_t type of status
   5131  *              NO_ERROR  -- success
   5132  *              none-zero failure code
   5133  *==========================================================================*/
   5134 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
   5135 {
   5136     int rc = NO_ERROR;
   5137 
   5138     // Update stream info configuration
   5139     rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
   5140     if (rc != NO_ERROR) {
   5141         LOGE("setStreamConfigure failed %d", rc);
   5142         return rc;
   5143     }
   5144 
   5145     return rc;
   5146 }
   5147 
   5148 /*===========================================================================
   5149  * FUNCTION   : longShot
   5150  *
   5151  * DESCRIPTION: Queue one more ZSL frame
   5152  *              in the longshot pipe.
   5153  *
   5154  * PARAMETERS : none
   5155  *
   5156  * RETURN     : int32_t type of status
   5157  *              NO_ERROR  -- success
   5158  *              none-zero failure code
   5159  *==========================================================================*/
   5160 int32_t QCamera2HardwareInterface::longShot()
   5161 {
   5162     int32_t rc = NO_ERROR;
   5163     uint8_t numSnapshots = mParameters.getNumOfSnapshots();
   5164     QCameraPicChannel *pChannel = NULL;
   5165 
   5166     if (mParameters.isZSLMode()) {
   5167         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   5168     } else {
   5169         pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
   5170     }
   5171 
   5172     if (NULL != pChannel) {
   5173         mm_camera_req_buf_t buf;
   5174         memset(&buf, 0x0, sizeof(buf));
   5175         buf.type = MM_CAMERA_REQ_SUPER_BUF;
   5176         buf.num_buf_requested = numSnapshots;
   5177         rc = pChannel->takePicture(&buf);
   5178     } else {
   5179         LOGE("Capture channel not initialized!");
   5180         rc = NO_INIT;
   5181         goto end;
   5182     }
   5183 
   5184 end:
   5185     return rc;
   5186 }
   5187 
   5188 /*===========================================================================
   5189  * FUNCTION   : stopCaptureChannel
   5190  *
   5191  * DESCRIPTION: Stops capture channel
   5192  *
   5193  * PARAMETERS :
   5194  *   @destroy : Set to true to stop and delete camera channel.
   5195  *              Set to false to only stop capture channel.
   5196  *
   5197  * RETURN     : int32_t type of status
   5198  *              NO_ERROR  -- success
   5199  *              none-zero failure code
   5200  *==========================================================================*/
   5201 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
   5202 {
   5203     int rc = NO_ERROR;
   5204     if (mParameters.isJpegPictureFormat() ||
   5205         mParameters.isNV16PictureFormat() ||
   5206         mParameters.isNV21PictureFormat()) {
   5207         mParameters.setQuadraCfaMode(false, true);
   5208         rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
   5209         if (destroy && (NO_ERROR == rc)) {
   5210             // Destroy camera channel but dont release context
   5211             waitDeferredWork(mJpegJob);
   5212             rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
   5213         }
   5214     }
   5215 
   5216     return rc;
   5217 }
   5218 
   5219 /*===========================================================================
   5220  * FUNCTION   : cancelPicture
   5221  *
   5222  * DESCRIPTION: cancel picture impl
   5223  *
   5224  * PARAMETERS : none
   5225  *
   5226  * RETURN     : int32_t type of status
   5227  *              NO_ERROR  -- success
   5228  *              none-zero failure code
   5229  *==========================================================================*/
   5230 int QCamera2HardwareInterface::cancelPicture()
   5231 {
   5232     waitDeferredWork(mReprocJob);
   5233     waitDeferredWork(mJpegJob);
   5234 
   5235     //stop post processor
   5236     m_postprocessor.stop();
   5237 
   5238     unconfigureAdvancedCapture();
   5239     LOGH("Enable display frames again");
   5240     setDisplaySkip(FALSE);
   5241 
   5242     if (!mLongshotEnabled) {
   5243         m_perfLock.lock_rel();
   5244     }
   5245 
   5246     if (mParameters.isZSLMode()) {
   5247         QCameraPicChannel *pPicChannel = NULL;
   5248         if (mParameters.getofflineRAW()) {
   5249             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
   5250         } else {
   5251             pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   5252         }
   5253         if (NULL != pPicChannel) {
   5254             pPicChannel->cancelPicture();
   5255             stopRAWChannel();
   5256             stopAdvancedCapture(pPicChannel);
   5257         }
   5258     } else {
   5259 
   5260         // normal capture case
   5261         if (mParameters.isJpegPictureFormat() ||
   5262             mParameters.isNV16PictureFormat() ||
   5263             mParameters.isNV21PictureFormat()) {
   5264             stopChannel(QCAMERA_CH_TYPE_CAPTURE);
   5265             delChannel(QCAMERA_CH_TYPE_CAPTURE);
   5266         } else {
   5267             stopChannel(QCAMERA_CH_TYPE_RAW);
   5268             delChannel(QCAMERA_CH_TYPE_RAW);
   5269         }
   5270     }
   5271 
   5272     return NO_ERROR;
   5273 }
   5274 
   5275 /*===========================================================================
   5276  * FUNCTION   : captureDone
   5277  *
   5278  * DESCRIPTION: Function called when the capture is completed before encoding
   5279  *
   5280  * PARAMETERS : none
   5281  *
   5282  * RETURN     : none
   5283  *==========================================================================*/
   5284 void QCamera2HardwareInterface::captureDone()
   5285 {
   5286     qcamera_sm_internal_evt_payload_t *payload =
   5287        (qcamera_sm_internal_evt_payload_t *)
   5288        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   5289     if (NULL != payload) {
   5290         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   5291         payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
   5292         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   5293         if (rc != NO_ERROR) {
   5294             LOGE("processEvt ZSL capture done failed");
   5295             free(payload);
   5296             payload = NULL;
   5297         }
   5298     } else {
   5299         LOGE("No memory for ZSL capture done event");
   5300     }
   5301 }
   5302 
   5303 /*===========================================================================
   5304  * FUNCTION   : Live_Snapshot_thread
   5305  *
   5306  * DESCRIPTION: Seperate thread for taking live snapshot during recording
   5307  *
   5308  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
   5309  *
   5310  * RETURN     : none
   5311  *==========================================================================*/
   5312 void* Live_Snapshot_thread (void* data)
   5313 {
   5314 
   5315     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
   5316     if (!hw) {
   5317         LOGE("take_picture_thread: NULL camera device");
   5318         return (void *)BAD_VALUE;
   5319     }
   5320     if (hw->bLiveSnapshot) {
   5321         hw->takeLiveSnapshot_internal();
   5322     } else {
   5323         hw->cancelLiveSnapshot_internal();
   5324     }
   5325     return (void* )NULL;
   5326 }
   5327 
   5328 /*===========================================================================
   5329  * FUNCTION   : Int_Pic_thread
   5330  *
   5331  * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
   5332  *
   5333  * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
   5334  *
   5335  * RETURN     : none
   5336  *==========================================================================*/
   5337 void* Int_Pic_thread (void* data)
   5338 {
   5339     int rc = NO_ERROR;
   5340 
   5341     QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
   5342 
   5343     if (!hw) {
   5344         LOGE("take_picture_thread: NULL camera device");
   5345         return (void *)BAD_VALUE;
   5346     }
   5347 
   5348     bool JpegMemOpt = false;
   5349     char raw_format[PROPERTY_VALUE_MAX];
   5350 
   5351     memset(raw_format, 0, sizeof(raw_format));
   5352 
   5353     rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
   5354     if (rc == NO_ERROR) {
   5355         hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
   5356     } else {
   5357         //Snapshot attempt not successful, we need to do cleanup here
   5358         hw->clearIntPendingEvents();
   5359     }
   5360 
   5361     return (void* )NULL;
   5362 }
   5363 
   5364 /*===========================================================================
   5365  * FUNCTION   : takeLiveSnapshot
   5366  *
   5367  * DESCRIPTION: take live snapshot during recording
   5368  *
   5369  * PARAMETERS : none
   5370  *
   5371  * RETURN     : int32_t type of status
   5372  *              NO_ERROR  -- success
   5373  *              none-zero failure code
   5374  *==========================================================================*/
   5375 int QCamera2HardwareInterface::takeLiveSnapshot()
   5376 {
   5377     int rc = NO_ERROR;
   5378     if (mLiveSnapshotThread != 0) {
   5379         pthread_join(mLiveSnapshotThread,NULL);
   5380         mLiveSnapshotThread = 0;
   5381     }
   5382     bLiveSnapshot = true;
   5383     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
   5384     if (!rc) {
   5385         pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
   5386     }
   5387     return rc;
   5388 }
   5389 
   5390 /*===========================================================================
   5391  * FUNCTION   : takePictureInternal
   5392  *
   5393  * DESCRIPTION: take snapshot triggered by backend
   5394  *
   5395  * PARAMETERS : none
   5396  *
   5397  * RETURN     : int32_t type of status
   5398  *              NO_ERROR  -- success
   5399  *              none-zero failure code
   5400  *==========================================================================*/
   5401 int QCamera2HardwareInterface::takePictureInternal()
   5402 {
   5403     int rc = NO_ERROR;
   5404     rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
   5405     if (!rc) {
   5406         pthread_setname_np(mIntPicThread, "CAM_IntPic");
   5407     }
   5408     return rc;
   5409 }
   5410 
   5411 /*===========================================================================
   5412  * FUNCTION   : checkIntPicPending
   5413  *
   5414  * DESCRIPTION: timed wait for jpeg completion event, and send
   5415  *                        back completion event to backend
   5416  *
   5417  * PARAMETERS : none
   5418  *
   5419  * RETURN     : none
   5420  *==========================================================================*/
   5421 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
   5422 {
   5423     bool bSendToBackend = true;
   5424     cam_int_evt_params_t params;
   5425     int rc = NO_ERROR;
   5426 
   5427     struct timespec   ts;
   5428     struct timeval    tp;
   5429     gettimeofday(&tp, NULL);
   5430     ts.tv_sec  = tp.tv_sec + 5;
   5431     ts.tv_nsec = tp.tv_usec * 1000;
   5432 
   5433     if (true == m_bIntJpegEvtPending ||
   5434         (true == m_bIntRawEvtPending)) {
   5435         //Waiting in HAL for snapshot taken notification
   5436         pthread_mutex_lock(&m_int_lock);
   5437         rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
   5438         if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
   5439             //Hit a timeout, or some spurious activity
   5440             bSendToBackend = false;
   5441         }
   5442 
   5443         if (true == m_bIntJpegEvtPending) {
   5444             params.event_type = 0;
   5445             mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
   5446         } else if (true == m_bIntRawEvtPending) {
   5447             params.event_type = 1;
   5448             mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
   5449         }
   5450         pthread_mutex_unlock(&m_int_lock);
   5451 
   5452         if (true == m_bIntJpegEvtPending) {
   5453             //Attempting to restart preview after taking JPEG snapshot
   5454             lockAPI();
   5455             rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
   5456             unlockAPI();
   5457             m_postprocessor.setJpegMemOpt(JpegMemOpt);
   5458         } else if (true == m_bIntRawEvtPending) {
   5459             //Attempting to restart preview after taking RAW snapshot
   5460             stopChannel(QCAMERA_CH_TYPE_RAW);
   5461             delChannel(QCAMERA_CH_TYPE_RAW);
   5462             //restoring the old raw format
   5463             property_set("persist.camera.raw.format", raw_format);
   5464         }
   5465 
   5466         if (true == bSendToBackend) {
   5467             //send event back to server with the file path
   5468             params.dim = m_postprocessor.m_dst_dim;
   5469             memcpy(&params.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
   5470             memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
   5471             params.size = mBackendFileSize;
   5472             rc = mParameters.setIntEvent(params);
   5473         }
   5474 
   5475         clearIntPendingEvents();
   5476     }
   5477 
   5478     return;
   5479 }
   5480 
   5481 /*===========================================================================
   5482  * FUNCTION   : takeBackendPic_internal
   5483  *
   5484  * DESCRIPTION: take snapshot triggered by backend
   5485  *
   5486  * PARAMETERS : none
   5487  *
   5488  * RETURN     : int32_t type of status
   5489  *              NO_ERROR  -- success
   5490  *              none-zero failure code
   5491  *==========================================================================*/
   5492 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
   5493 {
   5494     int rc = NO_ERROR;
   5495     qcamera_api_result_t apiResult;
   5496 
   5497     lockAPI();
   5498     //Set rotation value from user settings as Jpeg rotation
   5499     //to configure back-end modules.
   5500     mParameters.setJpegRotation(mParameters.getRotation());
   5501 
   5502     setRetroPicture(0);
   5503     /* Prepare snapshot in case LED needs to be flashed */
   5504     if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
   5505         // Start Preparing for normal Frames
   5506         LOGH("Start Prepare Snapshot");
   5507         /* Prepare snapshot in case LED needs to be flashed */
   5508         rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
   5509         if (rc == NO_ERROR) {
   5510             waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
   5511             rc = apiResult.status;
   5512         }
   5513         LOGH("Prep Snapshot done rc = %d", rc);
   5514         mPrepSnapRun = true;
   5515     }
   5516     unlockAPI();
   5517 
   5518     if (true == m_bIntJpegEvtPending) {
   5519         //Attempting to take JPEG snapshot
   5520         if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   5521             LOGE("Init PProc Deferred work failed");
   5522             return UNKNOWN_ERROR;
   5523         }
   5524         *JpegMemOpt = m_postprocessor.getJpegMemOpt();
   5525         m_postprocessor.setJpegMemOpt(false);
   5526 
   5527         /* capture */
   5528         lockAPI();
   5529         LOGH("Capturing internal snapshot");
   5530         rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
   5531         if (rc == NO_ERROR) {
   5532             waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
   5533             rc = apiResult.status;
   5534         }
   5535         unlockAPI();
   5536     } else if (true == m_bIntRawEvtPending) {
   5537         //Attempting to take RAW snapshot
   5538         (void)JpegMemOpt;
   5539         stopPreview();
   5540 
   5541         //getting the existing raw format type
   5542         property_get("persist.camera.raw.format", raw_format, "17");
   5543         //setting it to a default know value for this task
   5544         property_set("persist.camera.raw.format", "18");
   5545 
   5546         rc = addChannel(QCAMERA_CH_TYPE_RAW);
   5547         if (rc == NO_ERROR) {
   5548             // start postprocessor
   5549             if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   5550                 LOGE("Init PProc Deferred work failed");
   5551                 return UNKNOWN_ERROR;
   5552             }
   5553             rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
   5554             if (rc != NO_ERROR) {
   5555                 LOGE("cannot start postprocessor");
   5556                 delChannel(QCAMERA_CH_TYPE_RAW);
   5557                 return rc;
   5558             }
   5559 
   5560             rc = startChannel(QCAMERA_CH_TYPE_RAW);
   5561             if (rc != NO_ERROR) {
   5562                 LOGE("cannot start raw channel");
   5563                 m_postprocessor.stop();
   5564                 delChannel(QCAMERA_CH_TYPE_RAW);
   5565                 return rc;
   5566             }
   5567         } else {
   5568             LOGE("cannot add raw channel");
   5569             return rc;
   5570         }
   5571     }
   5572 
   5573     return rc;
   5574 }
   5575 
   5576 /*===========================================================================
   5577  * FUNCTION   : clearIntPendingEvents
   5578  *
   5579  * DESCRIPTION: clear internal pending events pertaining to backend
   5580  *                        snapshot requests
   5581  *
   5582  * PARAMETERS : none
   5583  *
   5584  * RETURN     : int32_t type of status
   5585  *              NO_ERROR  -- success
   5586  *              none-zero failure code
   5587  *==========================================================================*/
   5588 void QCamera2HardwareInterface::clearIntPendingEvents()
   5589 {
   5590     int rc = NO_ERROR;
   5591 
   5592     if (true == m_bIntRawEvtPending) {
   5593         preparePreview();
   5594         startPreview();
   5595     }
   5596     if (true == m_bIntJpegEvtPending) {
   5597         if (false == mParameters.isZSLMode()) {
   5598             lockAPI();
   5599             rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
   5600             unlockAPI();
   5601         }
   5602     }
   5603 
   5604     pthread_mutex_lock(&m_int_lock);
   5605     if (true == m_bIntJpegEvtPending) {
   5606         m_bIntJpegEvtPending = false;
   5607     } else if (true == m_bIntRawEvtPending) {
   5608         m_bIntRawEvtPending = false;
   5609     }
   5610     pthread_mutex_unlock(&m_int_lock);
   5611     return;
   5612 }
   5613 
   5614 /*===========================================================================
   5615  * FUNCTION   : takeLiveSnapshot_internal
   5616  *
   5617  * DESCRIPTION: take live snapshot during recording
   5618  *
   5619  * PARAMETERS : none
   5620  *
   5621  * RETURN     : int32_t type of status
   5622  *              NO_ERROR  -- success
   5623  *              none-zero failure code
   5624  *==========================================================================*/
   5625 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
   5626 {
   5627     int rc = NO_ERROR;
   5628 
   5629     QCameraChannel *pChannel = NULL;
   5630     QCameraChannel *pPreviewChannel = NULL;
   5631     QCameraStream  *pPreviewStream = NULL;
   5632     QCameraStream  *pStream = NULL;
   5633 
   5634     //Set rotation value from user settings as Jpeg rotation
   5635     //to configure back-end modules.
   5636     mParameters.setJpegRotation(mParameters.getRotation());
   5637 
   5638     // Configure advanced capture
   5639     rc = configureAdvancedCapture();
   5640     if (rc != NO_ERROR) {
   5641         LOGE("Unsupported capture call");
   5642         goto end;
   5643     }
   5644 
   5645     if (isLowPowerMode()) {
   5646         pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
   5647     } else {
   5648         pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   5649     }
   5650 
   5651     if (NULL == pChannel) {
   5652         LOGE("Snapshot/Video channel not initialized");
   5653         rc = NO_INIT;
   5654         goto end;
   5655     }
   5656 
   5657     // Check if all preview buffers are mapped before creating
   5658     // a jpeg session as preview stream buffers are queried during the same
   5659     pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   5660     if (pPreviewChannel != NULL) {
   5661         uint32_t numStreams = pPreviewChannel->getNumOfStreams();
   5662 
   5663         for (uint8_t i = 0 ; i < numStreams ; i++ ) {
   5664             pStream = pPreviewChannel->getStreamByIndex(i);
   5665             if (!pStream)
   5666                 continue;
   5667             if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
   5668                 pPreviewStream = pStream;
   5669                 break;
   5670             }
   5671         }
   5672 
   5673         if (pPreviewStream != NULL) {
   5674             Mutex::Autolock l(mMapLock);
   5675             QCameraMemory *pMemory = pStream->getStreamBufs();
   5676             if (!pMemory) {
   5677                 LOGE("Error!! pMemory is NULL");
   5678                 return -ENOMEM;
   5679             }
   5680 
   5681             uint8_t waitCnt = 2;
   5682             while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
   5683                 LOGL(" Waiting for preview buffers to be mapped");
   5684                 mMapCond.waitRelative(
   5685                         mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
   5686                 LOGL("Wait completed!!");
   5687                 waitCnt--;
   5688             }
   5689             // If all buffers are not mapped after retries, assert
   5690             assert(pMemory->checkIfAllBuffersMapped());
   5691         } else {
   5692             assert(pPreviewStream);
   5693         }
   5694     }
   5695 
   5696     DeferWorkArgs args;
   5697     memset(&args, 0, sizeof(DeferWorkArgs));
   5698 
   5699     args.pprocArgs = pChannel;
   5700 
   5701     // No need to wait for mInitPProcJob here, because it was
   5702     // queued in startPreview, and will definitely be processed before
   5703     // mReprocJob can begin.
   5704     mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
   5705             args);
   5706     if (mReprocJob == 0) {
   5707         LOGE("Failed to queue CMD_DEF_PPROC_START");
   5708         rc = -ENOMEM;
   5709         goto end;
   5710     }
   5711 
   5712     // Create JPEG session
   5713     mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
   5714             args);
   5715     if (mJpegJob == 0) {
   5716         LOGE("Failed to queue CREATE_JPEG_SESSION");
   5717         if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5718             LOGE("Reprocess Deferred work was failed");
   5719         }
   5720         m_postprocessor.stop();
   5721         rc = -ENOMEM;
   5722         goto end;
   5723     }
   5724 
   5725     if (isLowPowerMode()) {
   5726         mm_camera_req_buf_t buf;
   5727         memset(&buf, 0x0, sizeof(buf));
   5728         buf.type = MM_CAMERA_REQ_SUPER_BUF;
   5729         buf.num_buf_requested = 1;
   5730         rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
   5731         goto end;
   5732     }
   5733 
   5734     //Disable reprocess for 4K liveshot case
   5735     if (!mParameters.is4k2kVideoResolution()) {
   5736         rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
   5737         if (rc != NO_ERROR) {
   5738             LOGE("online rotation failed");
   5739             if (NO_ERROR != waitDeferredWork(mReprocJob)) {
   5740                 LOGE("Reprocess Deferred work was failed");
   5741             }
   5742             if (NO_ERROR != waitDeferredWork(mJpegJob)) {
   5743                 LOGE("Jpeg Deferred work was failed");
   5744             }
   5745             m_postprocessor.stop();
   5746             return rc;
   5747         }
   5748     }
   5749 
   5750     if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
   5751         QCameraStream *pStream = NULL;
   5752         for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
   5753             pStream = pChannel->getStreamByIndex(i);
   5754             if ((NULL != pStream) &&
   5755                     (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
   5756                 break;
   5757             }
   5758         }
   5759         if (pStream != NULL) {
   5760             LOGD("REQUEST_FRAMES event for TNR snapshot");
   5761             cam_stream_parm_buffer_t param;
   5762             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
   5763             param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
   5764             param.frameRequest.enableStream = 1;
   5765             rc = pStream->setParameter(param);
   5766             if (rc != NO_ERROR) {
   5767                 LOGE("Stream Event REQUEST_FRAMES failed");
   5768             }
   5769             goto end;
   5770         }
   5771     }
   5772 
   5773     // start snapshot channel
   5774     if ((rc == NO_ERROR) && (NULL != pChannel)) {
   5775         // Do not link metadata stream for 4K2k resolution
   5776         // as CPP processing would be done on snapshot stream and not
   5777         // reprocess stream
   5778         if (!mParameters.is4k2kVideoResolution()) {
   5779             // Find and try to link a metadata stream from preview channel
   5780             QCameraChannel *pMetaChannel = NULL;
   5781             QCameraStream *pMetaStream = NULL;
   5782             QCameraStream *pPreviewStream = NULL;
   5783 
   5784             if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   5785                 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
   5786                 uint32_t streamNum = pMetaChannel->getNumOfStreams();
   5787                 QCameraStream *pStream = NULL;
   5788                 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   5789                     pStream = pMetaChannel->getStreamByIndex(i);
   5790                     if (NULL != pStream) {
   5791                         if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
   5792                             pMetaStream = pStream;
   5793                         } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType())
   5794                                 && (!mParameters.isHfrMode())) {
   5795                             // Do not link preview stream for HFR live snapshot.
   5796                             // Thumbnail will not be derived from preview for HFR live snapshot.
   5797                             pPreviewStream = pStream;
   5798                         }
   5799                     }
   5800                 }
   5801             }
   5802 
   5803             if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
   5804                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   5805                 if (NO_ERROR != rc) {
   5806                     LOGE("Metadata stream link failed %d", rc);
   5807                 }
   5808             }
   5809             if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
   5810                 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
   5811                 if (NO_ERROR != rc) {
   5812                     LOGE("Preview stream link failed %d", rc);
   5813                 }
   5814             }
   5815         }
   5816         rc = pChannel->start();
   5817     }
   5818 
   5819 end:
   5820     if (rc != NO_ERROR) {
   5821         rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
   5822         rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
   5823     }
   5824     return rc;
   5825 }
   5826 
   5827 /*===========================================================================
   5828  * FUNCTION   : cancelLiveSnapshot
   5829  *
   5830  * DESCRIPTION: cancel current live snapshot request
   5831  *
   5832  * PARAMETERS : none
   5833  *
   5834  * RETURN     : int32_t type of status
   5835  *              NO_ERROR  -- success
   5836  *              none-zero failure code
   5837  *==========================================================================*/
   5838 int QCamera2HardwareInterface::cancelLiveSnapshot()
   5839 {
   5840     int rc = NO_ERROR;
   5841     if (mLiveSnapshotThread != 0) {
   5842         pthread_join(mLiveSnapshotThread,NULL);
   5843         mLiveSnapshotThread = 0;
   5844     }
   5845     bLiveSnapshot = false;
   5846     rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
   5847     if (!rc) {
   5848         pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap");
   5849     }
   5850     return rc;
   5851 }
   5852 
   5853 /*===========================================================================
   5854  * FUNCTION   : cancelLiveSnapshot_internal
   5855  *
   5856  * DESCRIPTION: cancel live snapshot during recording
   5857  *
   5858  * PARAMETERS : none
   5859  *
   5860  * RETURN     : int32_t type of status
   5861  *              NO_ERROR  -- success
   5862  *              none-zero failure code
   5863  *==========================================================================*/
   5864 int QCamera2HardwareInterface::cancelLiveSnapshot_internal() {
   5865     int rc = NO_ERROR;
   5866 
   5867     unconfigureAdvancedCapture();
   5868     LOGH("Enable display frames again");
   5869     setDisplaySkip(FALSE);
   5870 
   5871     if (!mLongshotEnabled) {
   5872         m_perfLock.lock_rel();
   5873     }
   5874 
   5875     //stop post processor
   5876     m_postprocessor.stop();
   5877 
   5878     // stop snapshot channel
   5879     if (!mParameters.isTNRSnapshotEnabled()) {
   5880         rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   5881     } else {
   5882         QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   5883         if (NULL != pChannel) {
   5884             QCameraStream *pStream = NULL;
   5885             for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
   5886                 pStream = pChannel->getStreamByIndex(i);
   5887                 if ((NULL != pStream) &&
   5888                         (CAM_STREAM_TYPE_SNAPSHOT ==
   5889                         pStream->getMyType())) {
   5890                     break;
   5891                 }
   5892             }
   5893             if (pStream != NULL) {
   5894                 LOGD("REQUEST_FRAMES event for TNR snapshot");
   5895                 cam_stream_parm_buffer_t param;
   5896                 memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
   5897                 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
   5898                 param.frameRequest.enableStream = 0;
   5899                 rc = pStream->setParameter(param);
   5900                 if (rc != NO_ERROR) {
   5901                     LOGE("Stream Event REQUEST_FRAMES failed");
   5902                 }
   5903             }
   5904         }
   5905     }
   5906 
   5907     return rc;
   5908 }
   5909 
   5910 /*===========================================================================
   5911  * FUNCTION   : putParameters
   5912  *
   5913  * DESCRIPTION: put parameters string impl
   5914  *
   5915  * PARAMETERS :
   5916  *   @parms   : parameters string to be released
   5917  *
   5918  * RETURN     : int32_t type of status
   5919  *              NO_ERROR  -- success
   5920  *              none-zero failure code
   5921  *==========================================================================*/
   5922 int QCamera2HardwareInterface::putParameters(char *parms)
   5923 {
   5924     free(parms);
   5925     return NO_ERROR;
   5926 }
   5927 
   5928 /*===========================================================================
   5929  * FUNCTION   : sendCommand
   5930  *
   5931  * DESCRIPTION: send command impl
   5932  *
   5933  * PARAMETERS :
   5934  *   @command : command to be executed
   5935  *   @arg1    : optional argument 1
   5936  *   @arg2    : optional argument 2
   5937  *
   5938  * RETURN     : int32_t type of status
   5939  *              NO_ERROR  -- success
   5940  *              none-zero failure code
   5941  *==========================================================================*/
   5942 int QCamera2HardwareInterface::sendCommand(int32_t command,
   5943         __unused int32_t &arg1, __unused int32_t &arg2)
   5944 {
   5945     int rc = NO_ERROR;
   5946 
   5947     switch (command) {
   5948 #ifndef VANILLA_HAL
   5949     case CAMERA_CMD_LONGSHOT_ON:
   5950         m_perfLock.lock_acq();
   5951         arg1 = arg2 = 0;
   5952         // Longshot can only be enabled when image capture
   5953         // is not active.
   5954         if ( !m_stateMachine.isCaptureRunning() ) {
   5955             LOGI("Longshot Enabled");
   5956             mLongshotEnabled = true;
   5957             rc = mParameters.setLongshotEnable(mLongshotEnabled);
   5958 
   5959             // Due to recent buffer count optimizations
   5960             // ZSL might run with considerably less buffers
   5961             // when not in longshot mode. Preview needs to
   5962             // restart in this case.
   5963             if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
   5964                 QCameraChannel *pChannel = NULL;
   5965                 QCameraStream *pSnapStream = NULL;
   5966                 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   5967                 if (NULL != pChannel) {
   5968                     QCameraStream *pStream = NULL;
   5969                     for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
   5970                         pStream = pChannel->getStreamByIndex(i);
   5971                         if (pStream != NULL) {
   5972                             if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
   5973                                 pSnapStream = pStream;
   5974                                 break;
   5975                             }
   5976                         }
   5977                     }
   5978                     if (NULL != pSnapStream) {
   5979                         uint8_t required = 0;
   5980                         required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
   5981                         if (pSnapStream->getBufferCount() < required) {
   5982                             // We restart here, to reset the FPS and no
   5983                             // of buffers as per the requirement of longshot usecase.
   5984                             arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
   5985                             if (getRelatedCamSyncInfo()->sync_control ==
   5986                                     CAM_SYNC_RELATED_SENSORS_ON) {
   5987                                 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
   5988                             }
   5989                         }
   5990                     }
   5991                 }
   5992             }
   5993             //
   5994             mPrepSnapRun = false;
   5995             mCACDoneReceived = FALSE;
   5996         } else {
   5997             rc = NO_INIT;
   5998         }
   5999         break;
   6000     case CAMERA_CMD_LONGSHOT_OFF:
   6001         m_perfLock.lock_rel();
   6002         if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
   6003             cancelPicture();
   6004             processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
   6005             QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
   6006             if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
   6007                 mCameraHandle->ops->stop_zsl_snapshot(
   6008                         mCameraHandle->camera_handle,
   6009                         pZSLChannel->getMyHandle());
   6010             }
   6011         }
   6012         mPrepSnapRun = false;
   6013         LOGI("Longshot Disabled");
   6014         mLongshotEnabled = false;
   6015         rc = mParameters.setLongshotEnable(mLongshotEnabled);
   6016         mCACDoneReceived = FALSE;
   6017         break;
   6018     case CAMERA_CMD_HISTOGRAM_ON:
   6019     case CAMERA_CMD_HISTOGRAM_OFF:
   6020         rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
   6021         LOGH("Histogram -> %s",
   6022               mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
   6023         break;
   6024 #endif
   6025     case CAMERA_CMD_START_FACE_DETECTION:
   6026     case CAMERA_CMD_STOP_FACE_DETECTION:
   6027         mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
   6028         rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
   6029         LOGH("FaceDetection -> %s",
   6030               mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
   6031         break;
   6032 #ifndef VANILLA_HAL
   6033     case CAMERA_CMD_HISTOGRAM_SEND_DATA:
   6034 #endif
   6035     default:
   6036         rc = NO_ERROR;
   6037         break;
   6038     }
   6039     return rc;
   6040 }
   6041 
   6042 /*===========================================================================
   6043  * FUNCTION   : registerFaceImage
   6044  *
   6045  * DESCRIPTION: register face image impl
   6046  *
   6047  * PARAMETERS :
   6048  *   @img_ptr : ptr to image buffer
   6049  *   @config  : ptr to config struct about input image info
   6050  *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
   6051  *
   6052  * RETURN     : int32_t type of status
   6053  *              NO_ERROR  -- success
   6054  *              none-zero failure code
   6055  *==========================================================================*/
   6056 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
   6057                                                  cam_pp_offline_src_config_t *config,
   6058                                                  int32_t &faceID)
   6059 {
   6060     int rc = NO_ERROR;
   6061     faceID = -1;
   6062 
   6063     if (img_ptr == NULL || config == NULL) {
   6064         LOGE("img_ptr or config is NULL");
   6065         return BAD_VALUE;
   6066     }
   6067 
   6068     // allocate ion memory for source image
   6069     QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
   6070     if (imgBuf == NULL) {
   6071         LOGE("Unable to new heap memory obj for image buf");
   6072         return NO_MEMORY;
   6073     }
   6074 
   6075     rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len, NON_SECURE);
   6076     if (rc < 0) {
   6077         LOGE("Unable to allocate heap memory for image buf");
   6078         delete imgBuf;
   6079         return NO_MEMORY;
   6080     }
   6081 
   6082     void *pBufPtr = imgBuf->getPtr(0);
   6083     if (pBufPtr == NULL) {
   6084         LOGE("image buf is NULL");
   6085         imgBuf->deallocate();
   6086         delete imgBuf;
   6087         return NO_MEMORY;
   6088     }
   6089     memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
   6090 
   6091     cam_pp_feature_config_t pp_feature;
   6092     memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
   6093     pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
   6094     QCameraReprocessChannel *pChannel =
   6095         addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
   6096 
   6097     if (pChannel == NULL) {
   6098         LOGE("fail to add offline reprocess channel");
   6099         imgBuf->deallocate();
   6100         delete imgBuf;
   6101         return UNKNOWN_ERROR;
   6102     }
   6103 
   6104     rc = pChannel->start();
   6105     if (rc != NO_ERROR) {
   6106         LOGE("Cannot start reprocess channel");
   6107         imgBuf->deallocate();
   6108         delete imgBuf;
   6109         delete pChannel;
   6110         return rc;
   6111     }
   6112 
   6113     ssize_t bufSize = imgBuf->getSize(0);
   6114     if (BAD_INDEX != bufSize) {
   6115         rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0),
   6116                 (size_t)bufSize, faceID);
   6117     } else {
   6118         LOGE("Failed to retrieve buffer size (bad index)");
   6119         return UNKNOWN_ERROR;
   6120     }
   6121 
   6122     // done with register face image, free imgbuf and delete reprocess channel
   6123     imgBuf->deallocate();
   6124     delete imgBuf;
   6125     imgBuf = NULL;
   6126     pChannel->stop();
   6127     delete pChannel;
   6128     pChannel = NULL;
   6129 
   6130     return rc;
   6131 }
   6132 
   6133 /*===========================================================================
   6134  * FUNCTION   : release
   6135  *
   6136  * DESCRIPTION: release camera resource impl
   6137  *
   6138  * PARAMETERS : none
   6139  *
   6140  * RETURN     : int32_t type of status
   6141  *              NO_ERROR  -- success
   6142  *              none-zero failure code
   6143  *==========================================================================*/
   6144 int QCamera2HardwareInterface::release()
   6145 {
   6146     // stop and delete all channels
   6147     for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
   6148         if (m_channels[i] != NULL) {
   6149             stopChannel((qcamera_ch_type_enum_t)i);
   6150             delChannel((qcamera_ch_type_enum_t)i);
   6151         }
   6152     }
   6153 
   6154     return NO_ERROR;
   6155 }
   6156 
   6157 /*===========================================================================
   6158  * FUNCTION   : dump
   6159  *
   6160  * DESCRIPTION: camera status dump impl
   6161  *
   6162  * PARAMETERS :
   6163  *   @fd      : fd for the buffer to be dumped with camera status
   6164  *
   6165  * RETURN     : int32_t type of status
   6166  *              NO_ERROR  -- success
   6167  *              none-zero failure code
   6168  *==========================================================================*/
   6169 int QCamera2HardwareInterface::dump(int fd)
   6170 {
   6171     dprintf(fd, "\n Camera HAL information Begin \n");
   6172     dprintf(fd, "Camera ID: %d \n", mCameraId);
   6173     dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
   6174     dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
   6175     dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
   6176     dprintf(fd, "\n Camera HAL information End \n");
   6177 
   6178     /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
   6179        debug level property */
   6180     mParameters.updateDebugLevel();
   6181     return NO_ERROR;
   6182 }
   6183 
   6184 /*===========================================================================
   6185  * FUNCTION   : processAPI
   6186  *
   6187  * DESCRIPTION: process API calls from upper layer
   6188  *
   6189  * PARAMETERS :
   6190  *   @api         : API to be processed
   6191  *   @api_payload : ptr to API payload if any
   6192  *
   6193  * RETURN     : int32_t type of status
   6194  *              NO_ERROR  -- success
   6195  *              none-zero failure code
   6196  *==========================================================================*/
   6197 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
   6198 {
   6199     int ret = DEAD_OBJECT;
   6200 
   6201     if (m_smThreadActive) {
   6202         ret = m_stateMachine.procAPI(api, api_payload);
   6203     }
   6204 
   6205     return ret;
   6206 }
   6207 
   6208 /*===========================================================================
   6209  * FUNCTION   : processEvt
   6210  *
   6211  * DESCRIPTION: process Evt from backend via mm-camera-interface
   6212  *
   6213  * PARAMETERS :
   6214  *   @evt         : event type to be processed
   6215  *   @evt_payload : ptr to event payload if any
   6216  *
   6217  * RETURN     : int32_t type of status
   6218  *              NO_ERROR  -- success
   6219  *              none-zero failure code
   6220  *==========================================================================*/
   6221 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
   6222 {
   6223     return m_stateMachine.procEvt(evt, evt_payload);
   6224 }
   6225 
   6226 /*===========================================================================
   6227  * FUNCTION   : processSyncEvt
   6228  *
   6229  * DESCRIPTION: process synchronous Evt from backend
   6230  *
   6231  * PARAMETERS :
   6232  *   @evt         : event type to be processed
   6233  *   @evt_payload : ptr to event payload if any
   6234  *
   6235  * RETURN     : int32_t type of status
   6236  *              NO_ERROR  -- success
   6237  *              none-zero failure code
   6238  *==========================================================================*/
   6239 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
   6240 {
   6241     int rc = NO_ERROR;
   6242 
   6243     pthread_mutex_lock(&m_evtLock);
   6244     rc =  processEvt(evt, evt_payload);
   6245     if (rc == NO_ERROR) {
   6246         memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
   6247         while (m_evtResult.request_api != evt) {
   6248             pthread_cond_wait(&m_evtCond, &m_evtLock);
   6249         }
   6250         rc =  m_evtResult.status;
   6251     }
   6252     pthread_mutex_unlock(&m_evtLock);
   6253 
   6254     return rc;
   6255 }
   6256 
   6257 /*===========================================================================
   6258  * FUNCTION   : evtHandle
   6259  *
   6260  * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
   6261  *
   6262  * PARAMETERS :
   6263  *   @camera_handle : event type to be processed
   6264  *   @evt           : ptr to event
   6265  *   @user_data     : user data ptr
   6266  *
   6267  * RETURN     : none
   6268  *==========================================================================*/
   6269 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
   6270                                           mm_camera_event_t *evt,
   6271                                           void *user_data)
   6272 {
   6273     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
   6274     if (obj && evt) {
   6275         mm_camera_event_t *payload =
   6276             (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
   6277         if (NULL != payload) {
   6278             *payload = *evt;
   6279             //peek into the event, if this is an eztune event from server,
   6280             //then we don't need to post it to the SM Qs, we shud directly
   6281             //spawn a thread and get the job done (jpeg or raw snapshot)
   6282             switch (payload->server_event_type) {
   6283                 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
   6284                     //Received JPEG trigger from eztune
   6285                     if (false == obj->m_bIntJpegEvtPending) {
   6286                         pthread_mutex_lock(&obj->m_int_lock);
   6287                         obj->m_bIntJpegEvtPending = true;
   6288                         pthread_mutex_unlock(&obj->m_int_lock);
   6289                         obj->takePictureInternal();
   6290                     }
   6291                     free(payload);
   6292                     break;
   6293                 case CAM_EVENT_TYPE_INT_TAKE_RAW:
   6294                     //Received RAW trigger from eztune
   6295                     if (false == obj->m_bIntRawEvtPending) {
   6296                         pthread_mutex_lock(&obj->m_int_lock);
   6297                         obj->m_bIntRawEvtPending = true;
   6298                         pthread_mutex_unlock(&obj->m_int_lock);
   6299                         obj->takePictureInternal();
   6300                     }
   6301                     free(payload);
   6302                     break;
   6303                 case CAM_EVENT_TYPE_DAEMON_DIED:
   6304                     {
   6305                         Mutex::Autolock l(obj->mDefLock);
   6306                         obj->mDefCond.broadcast();
   6307                         LOGH("broadcast mDefCond signal\n");
   6308                     }
   6309                 default:
   6310                     obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
   6311                     break;
   6312             }
   6313         }
   6314     } else {
   6315         LOGE("NULL user_data");
   6316     }
   6317 }
   6318 
   6319 /*===========================================================================
   6320  * FUNCTION   : jpegEvtHandle
   6321  *
   6322  * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
   6323  *
   6324  * PARAMETERS :
   6325  *   @status    : status of jpeg job
   6326  *   @client_hdl: jpeg client handle
   6327  *   @jobId     : jpeg job Id
   6328  *   @p_ouput   : ptr to jpeg output result struct
   6329  *   @userdata  : user data ptr
   6330  *
   6331  * RETURN     : none
   6332  *==========================================================================*/
   6333 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
   6334                                               uint32_t /*client_hdl*/,
   6335                                               uint32_t jobId,
   6336                                               mm_jpeg_output_t *p_output,
   6337                                               void *userdata)
   6338 {
   6339     QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
   6340     if (obj) {
   6341         qcamera_jpeg_evt_payload_t *payload =
   6342             (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
   6343         if (NULL != payload) {
   6344             memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
   6345             payload->status = status;
   6346             payload->jobId = jobId;
   6347             if (p_output != NULL) {
   6348                 payload->out_data = *p_output;
   6349             }
   6350             obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
   6351         }
   6352     } else {
   6353         LOGE("NULL user_data");
   6354     }
   6355 }
   6356 
   6357 /*===========================================================================
   6358  * FUNCTION   : thermalEvtHandle
   6359  *
   6360  * DESCRIPTION: routine to handle thermal event notification
   6361  *
   6362  * PARAMETERS :
   6363  *   @level      : thermal level
   6364  *   @userdata   : userdata passed in during registration
   6365  *   @data       : opaque data from thermal client
   6366  *
   6367  * RETURN     : int32_t type of status
   6368  *              NO_ERROR  -- success
   6369  *              none-zero failure code
   6370  *==========================================================================*/
   6371 int QCamera2HardwareInterface::thermalEvtHandle(
   6372         qcamera_thermal_level_enum_t *level, void *userdata, void *data)
   6373 {
   6374     if (!mCameraOpened) {
   6375         LOGH("Camera is not opened, no need to handle thermal evt");
   6376         return NO_ERROR;
   6377     }
   6378 
   6379     // Make sure thermal events are logged
   6380     LOGH("level = %d, userdata = %p, data = %p",
   6381          *level, userdata, data);
   6382     //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
   6383     // becomes an aync call. This also means we can only pass payload
   6384     // by value, not by address.
   6385     return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
   6386 }
   6387 
   6388 /*===========================================================================
   6389  * FUNCTION   : sendEvtNotify
   6390  *
   6391  * DESCRIPTION: send event notify to notify thread
   6392  *
   6393  * PARAMETERS :
   6394  *   @msg_type: msg type to be sent
   6395  *   @ext1    : optional extension1
   6396  *   @ext2    : optional extension2
   6397  *
   6398  * RETURN     : int32_t type of status
   6399  *              NO_ERROR  -- success
   6400  *              none-zero failure code
   6401  *==========================================================================*/
   6402 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
   6403                                                  int32_t ext1,
   6404                                                  int32_t ext2)
   6405 {
   6406     qcamera_callback_argm_t cbArg;
   6407     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   6408     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
   6409     cbArg.msg_type = msg_type;
   6410     cbArg.ext1 = ext1;
   6411     cbArg.ext2 = ext2;
   6412     return m_cbNotifier.notifyCallback(cbArg);
   6413 }
   6414 
   6415 /*===========================================================================
   6416  * FUNCTION   : processAEInfo
   6417  *
   6418  * DESCRIPTION: process AE updates
   6419  *
   6420  * PARAMETERS :
   6421  *   @ae_params: current AE parameters
   6422  *
   6423  * RETURN     : None
   6424  *==========================================================================*/
   6425 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
   6426 {
   6427     mParameters.updateAEInfo(ae_params);
   6428     if (mParameters.isInstantAECEnabled()) {
   6429         // Reset Instant AEC info only if instant aec enabled.
   6430         bool bResetInstantAec = false;
   6431         if (ae_params.settled) {
   6432             // If AEC settled, reset instant AEC
   6433             bResetInstantAec = true;
   6434         } else if ((mParameters.isInstantCaptureEnabled()) &&
   6435                 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
   6436             // if AEC not settled, and instant capture enabled,
   6437             // reset instant AEC only when frame count is
   6438             // more or equal to AEC frame bound value.
   6439             bResetInstantAec = true;
   6440         } else if ((mParameters.isInstantAECEnabled()) &&
   6441                 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
   6442             // if AEC not settled, and only instant AEC enabled,
   6443             // reset instant AEC only when frame count is
   6444             // more or equal to AEC skip display frame bound value.
   6445             bResetInstantAec = true;
   6446         }
   6447 
   6448         if (bResetInstantAec) {
   6449             LOGD("setting instant AEC to false");
   6450             mParameters.setInstantAEC(false, true);
   6451             mInstantAecFrameCount = 0;
   6452         }
   6453     }
   6454     return NO_ERROR;
   6455 }
   6456 
   6457 /*===========================================================================
   6458  * FUNCTION   : processFocusPositionInfo
   6459  *
   6460  * DESCRIPTION: process AF updates
   6461  *
   6462  * PARAMETERS :
   6463  *   @cur_pos_info: current lens position
   6464  *
   6465  * RETURN     : None
   6466  *==========================================================================*/
   6467 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
   6468 {
   6469     mParameters.updateCurrentFocusPosition(cur_pos_info);
   6470     return NO_ERROR;
   6471 }
   6472 
   6473 /*===========================================================================
   6474  * FUNCTION   : processAutoFocusEvent
   6475  *
   6476  * DESCRIPTION: process auto focus event
   6477  *
   6478  * PARAMETERS :
   6479  *   @focus_data: struct containing auto focus result info
   6480  *
   6481  * RETURN     : int32_t type of status
   6482  *              NO_ERROR  -- success
   6483  *              none-zero failure code
   6484  *==========================================================================*/
   6485 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
   6486 {
   6487     int32_t ret = NO_ERROR;
   6488     LOGH("E");
   6489 
   6490     if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
   6491         // Ignore focus updates
   6492         LOGH("X Secondary Camera, no need to process!! ");
   6493         return ret;
   6494     }
   6495     cam_focus_mode_type focusMode = mParameters.getFocusMode();
   6496     LOGH("[AF_DBG]  focusMode=%d, focusState=%d isDepth=%d",
   6497              focusMode, focus_data.focus_state, focus_data.isDepth);
   6498 
   6499     switch (focusMode) {
   6500     case CAM_FOCUS_MODE_AUTO:
   6501     case CAM_FOCUS_MODE_MACRO:
   6502         // ignore AF event if AF was already cancelled meanwhile
   6503         if (!mActiveAF) {
   6504             break;
   6505         }
   6506         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
   6507         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
   6508                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6509             ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
   6510             mActiveAF = false; // reset the mActiveAF in this special case
   6511             break;
   6512         }
   6513 
   6514         //while transitioning from CAF->Auto/Macro, we might receive CAF related
   6515         //events (PASSIVE_*) due to timing. Ignore such events if any.
   6516         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
   6517                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6518                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
   6519             break;
   6520         }
   6521 
   6522         //This is just an intermediate update to HAL indicating focus is in progress. No need
   6523         //to send this event to app. Same applies to INACTIVE state as well.
   6524         if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
   6525                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6526             break;
   6527         }
   6528         // update focus distance
   6529         mParameters.updateFocusDistances(&focus_data.focus_dist);
   6530 
   6531         //flush any old snapshot frames in ZSL Q which are not focused.
   6532         if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
   6533             QCameraPicChannel *pZSLChannel =
   6534                     (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   6535             if (NULL != pZSLChannel) {
   6536                 //flush the zsl-buffer
   6537                 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
   6538                 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
   6539                 pZSLChannel->flushSuperbuffer(flush_frame_idx);
   6540             }
   6541         }
   6542 
   6543         //send event to app finally
   6544         LOGI("Send AF DOne event to app");
   6545         ret = sendEvtNotify(CAMERA_MSG_FOCUS,
   6546                             (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
   6547         break;
   6548     case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
   6549     case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
   6550 
   6551         // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
   6552         if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
   6553                 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
   6554             ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
   6555             mActiveAF = false; // reset the mActiveAF in this special case
   6556             break;
   6557         }
   6558 
   6559         //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
   6560         //process/wait for only ACTIVE_* events.
   6561         if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6562                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
   6563                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
   6564             break;
   6565         }
   6566 
   6567         if (!bDepthAFCallbacks && focus_data.isDepth &&
   6568                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) {
   6569             LOGD("Skip sending scan state to app, if depth focus");
   6570             break;
   6571         }
   6572 
   6573         //These are the AF states for which we need to send notification to app in CAF mode.
   6574         //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
   6575         //AF is triggered while in CAF mode)
   6576         if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6577                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
   6578                 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
   6579                 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
   6580 
   6581             // update focus distance
   6582             mParameters.updateFocusDistances(&focus_data.focus_dist);
   6583 
   6584             if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
   6585                 QCameraPicChannel *pZSLChannel =
   6586                         (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
   6587                 if (NULL != pZSLChannel) {
   6588                     //flush the zsl-buffer
   6589                     uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
   6590                     LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
   6591                     pZSLChannel->flushSuperbuffer(flush_frame_idx);
   6592                 }
   6593             }
   6594 
   6595             if (mActiveAF) {
   6596                 LOGI("Send AF Done event to app");
   6597             }
   6598             ret = sendEvtNotify(CAMERA_MSG_FOCUS,
   6599                     ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
   6600                     (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
   6601         }
   6602         ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
   6603                 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
   6604         break;
   6605     case CAM_FOCUS_MODE_INFINITY:
   6606     case CAM_FOCUS_MODE_FIXED:
   6607     case CAM_FOCUS_MODE_EDOF:
   6608     default:
   6609         LOGH("no ops for autofocus event in focusmode %d", focusMode);
   6610         break;
   6611     }
   6612 
   6613     //Reset mActiveAF once we receive focus done event
   6614     if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
   6615             (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
   6616         mActiveAF = false;
   6617     }
   6618 
   6619     LOGH("X");
   6620     return ret;
   6621 }
   6622 
   6623 /*===========================================================================
   6624  * FUNCTION   : processZoomEvent
   6625  *
   6626  * DESCRIPTION: process zoom event
   6627  *
   6628  * PARAMETERS :
   6629  *   @crop_info : crop info as a result of zoom operation
   6630  *
   6631  * RETURN     : int32_t type of status
   6632  *              NO_ERROR  -- success
   6633  *              none-zero failure code
   6634  *==========================================================================*/
   6635 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
   6636 {
   6637     int32_t ret = NO_ERROR;
   6638 
   6639     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   6640         if (m_channels[i] != NULL) {
   6641             ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
   6642         }
   6643     }
   6644     return ret;
   6645 }
   6646 
   6647 /*===========================================================================
   6648  * FUNCTION   : processZSLCaptureDone
   6649  *
   6650  * DESCRIPTION: process ZSL capture done events
   6651  *
   6652  * PARAMETERS : None
   6653  *
   6654  * RETURN     : int32_t type of status
   6655  *              NO_ERROR  -- success
   6656  *              none-zero failure code
   6657  *==========================================================================*/
   6658 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
   6659 {
   6660     int rc = NO_ERROR;
   6661 
   6662     if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
   6663         rc = unconfigureAdvancedCapture();
   6664     }
   6665 
   6666     return rc;
   6667 }
   6668 
   6669 /*===========================================================================
   6670  * FUNCTION   : processRetroAECUnlock
   6671  *
   6672  * DESCRIPTION: process retro burst AEC unlock events
   6673  *
   6674  * PARAMETERS : None
   6675  *
   6676  * RETURN     : int32_t type of status
   6677  *              NO_ERROR  -- success
   6678  *              none-zero failure code
   6679  *==========================================================================*/
   6680 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
   6681 {
   6682     int rc = NO_ERROR;
   6683 
   6684     LOGH("LED assisted AF Release AEC Lock");
   6685     rc = mParameters.setAecLock("false");
   6686     if (NO_ERROR != rc) {
   6687         LOGE("Error setting AEC lock");
   6688         return rc;
   6689     }
   6690 
   6691     rc = mParameters.commitParameters();
   6692     if (NO_ERROR != rc) {
   6693         LOGE("Error during camera parameter commit");
   6694     } else {
   6695         m_bLedAfAecLock = FALSE;
   6696     }
   6697 
   6698     return rc;
   6699 }
   6700 
   6701 /*===========================================================================
   6702  * FUNCTION   : processHDRData
   6703  *
   6704  * DESCRIPTION: process HDR scene events
   6705  *
   6706  * PARAMETERS :
   6707  *   @hdr_scene : HDR scene event data
   6708  *
   6709  * RETURN     : int32_t type of status
   6710  *              NO_ERROR  -- success
   6711  *              none-zero failure code
   6712  *==========================================================================*/
   6713 int32_t QCamera2HardwareInterface::processHDRData(
   6714         __unused cam_asd_hdr_scene_data_t hdr_scene)
   6715 {
   6716     int rc = NO_ERROR;
   6717 
   6718 #ifndef VANILLA_HAL
   6719     if (hdr_scene.is_hdr_scene &&
   6720       (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
   6721       mParameters.isAutoHDREnabled()) {
   6722         m_HDRSceneEnabled = true;
   6723     } else {
   6724         m_HDRSceneEnabled = false;
   6725     }
   6726     mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
   6727 
   6728     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
   6729 
   6730         size_t data_len = sizeof(int);
   6731         size_t buffer_len = 1 *sizeof(int)       //meta type
   6732                           + 1 *sizeof(int)       //data len
   6733                           + 1 *sizeof(int);      //data
   6734         camera_memory_t *hdrBuffer = mGetMemory(-1,
   6735                                                  buffer_len,
   6736                                                  1,
   6737                                                  mCallbackCookie);
   6738         if ( NULL == hdrBuffer ) {
   6739             LOGE("Not enough memory for auto HDR data");
   6740             return NO_MEMORY;
   6741         }
   6742 
   6743         int *pHDRData = (int *)hdrBuffer->data;
   6744         if (pHDRData == NULL) {
   6745             LOGE("memory data ptr is NULL");
   6746             return UNKNOWN_ERROR;
   6747         }
   6748 
   6749         pHDRData[0] = CAMERA_META_DATA_HDR;
   6750         pHDRData[1] = (int)data_len;
   6751         pHDRData[2] = m_HDRSceneEnabled;
   6752 
   6753         qcamera_callback_argm_t cbArg;
   6754         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   6755         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   6756         cbArg.msg_type = CAMERA_MSG_META_DATA;
   6757         cbArg.data = hdrBuffer;
   6758         cbArg.user_data = hdrBuffer;
   6759         cbArg.cookie = this;
   6760         cbArg.release_cb = releaseCameraMemory;
   6761         rc = m_cbNotifier.notifyCallback(cbArg);
   6762         if (rc != NO_ERROR) {
   6763             LOGE("fail sending auto HDR notification");
   6764             hdrBuffer->release(hdrBuffer);
   6765         }
   6766     }
   6767 
   6768     LOGH("hdr_scene_data: processHDRData: %d %f",
   6769           hdr_scene.is_hdr_scene,
   6770           hdr_scene.hdr_confidence);
   6771 
   6772 #endif
   6773   return rc;
   6774 }
   6775 
   6776 /*===========================================================================
   6777  * FUNCTION   : transAwbMetaToParams
   6778  *
   6779  * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
   6780  *
   6781  * PARAMETERS :
   6782  *   @awb_params : awb params from metadata callback
   6783  *
   6784  * RETURN     : int32_t type of status
   6785  *              NO_ERROR  -- success
   6786  *              none-zero failure code
   6787  *==========================================================================*/
   6788 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
   6789 {
   6790     mParameters.updateAWBParams(awb_params);
   6791     return NO_ERROR;
   6792 }
   6793 
   6794 /*===========================================================================
   6795  * FUNCTION   : processPrepSnapshotDone
   6796  *
   6797  * DESCRIPTION: process prep snapshot done event
   6798  *
   6799  * PARAMETERS :
   6800  *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
   6801  *                           i.e. whether need future frames for capture.
   6802  *
   6803  * RETURN     : int32_t type of status
   6804  *              NO_ERROR  -- success
   6805  *              none-zero failure code
   6806  *==========================================================================*/
   6807 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
   6808                         cam_prep_snapshot_state_t prep_snapshot_state)
   6809 {
   6810     int32_t ret = NO_ERROR;
   6811     LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
   6812             prep_snapshot_state);
   6813     if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
   6814         prep_snapshot_state == NEED_FUTURE_FRAME) {
   6815         LOGH("already handled in mm-camera-intf, no ops here");
   6816         if (isRetroPicture()) {
   6817             mParameters.setAecLock("true");
   6818             mParameters.commitParameters();
   6819             m_bLedAfAecLock = TRUE;
   6820         }
   6821     }
   6822     return ret;
   6823 }
   6824 
   6825 /*===========================================================================
   6826  * FUNCTION   : processASDUpdate
   6827  *
   6828  * DESCRIPTION: process ASD update event
   6829  *
   6830  * PARAMETERS :
   6831  *   @scene: selected scene mode
   6832  *
   6833  * RETURN     : int32_t type of status
   6834  *              NO_ERROR  -- success
   6835  *              none-zero failure code
   6836  *==========================================================================*/
   6837 int32_t QCamera2HardwareInterface::processASDUpdate(
   6838         __unused cam_asd_decision_t asd_decision)
   6839 {
   6840 #ifndef VANILLA_HAL
   6841     if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
   6842         size_t data_len = sizeof(cam_auto_scene_t);
   6843         size_t buffer_len = 1 *sizeof(int)       //meta type
   6844                 + 1 *sizeof(int)       //data len
   6845                 + data_len;            //data
   6846         camera_memory_t *asdBuffer = mGetMemory(-1,
   6847                 buffer_len, 1, mCallbackCookie);
   6848         if ( NULL == asdBuffer ) {
   6849             LOGE("Not enough memory for histogram data");
   6850             return NO_MEMORY;
   6851         }
   6852 
   6853         int *pASDData = (int *)asdBuffer->data;
   6854         if (pASDData == NULL) {
   6855             LOGE("memory data ptr is NULL");
   6856             return UNKNOWN_ERROR;
   6857         }
   6858 
   6859         pASDData[0] = CAMERA_META_DATA_ASD;
   6860         pASDData[1] = (int)data_len;
   6861         pASDData[2] = asd_decision.detected_scene;
   6862 
   6863         qcamera_callback_argm_t cbArg;
   6864         memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   6865         cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   6866         cbArg.msg_type = CAMERA_MSG_META_DATA;
   6867         cbArg.data = asdBuffer;
   6868         cbArg.user_data = asdBuffer;
   6869         cbArg.cookie = this;
   6870         cbArg.release_cb = releaseCameraMemory;
   6871         int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   6872         if (rc != NO_ERROR) {
   6873             LOGE("fail sending notification");
   6874             asdBuffer->release(asdBuffer);
   6875         }
   6876     }
   6877 #endif
   6878     return NO_ERROR;
   6879 }
   6880 
   6881 /*===========================================================================
   6882  * FUNCTION   : processJpegNotify
   6883  *
   6884  * DESCRIPTION: process jpeg event
   6885  *
   6886  * PARAMETERS :
   6887  *   @jpeg_evt: ptr to jpeg event payload
   6888  *
   6889  * RETURN     : int32_t type of status
   6890  *              NO_ERROR  -- success
   6891  *              none-zero failure code
   6892  *==========================================================================*/
   6893 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
   6894 {
   6895     return m_postprocessor.processJpegEvt(jpeg_evt);
   6896 }
   6897 
   6898 
   6899 /*===========================================================================
   6900  * FUNCTION   : processDCFOVControl
   6901  *
   6902  * DESCRIPTION: Fill Dual camera FOV control
   6903  *
   6904  * PARAMETERS : none
   6905  *
   6906  * RETURN     : int32_t type of status
   6907  *              NO_ERROR  -- success
   6908  *              none-zero failure code
   6909  *==========================================================================*/
   6910 int32_t QCamera2HardwareInterface::processDCFOVControl()
   6911 {
   6912     int32_t zoomLevel;
   6913     uint32_t camState = mActiveCamera;
   6914 
   6915     if (!isDualCamera()) {
   6916         return NO_ERROR;
   6917     }
   6918 
   6919     /*FOV control block needs to integrated here to decide dual camera
   6920     switch operation.
   6921     We can access application parameter, metadata buffer,
   6922     parameter buffer used for back-end here*/
   6923     zoomLevel = mParameters.getParmZoomLevel();
   6924     if (zoomLevel < 20) {
   6925         //WIDE Zone
   6926         LOGH("WIDE ZONE : %d and  %d", zoomLevel, prev_zoomLevel);
   6927         if (camState & MM_CAMERA_TYPE_AUX) {
   6928             //Suspend Aux
   6929             camState &= (~MM_CAMERA_TYPE_AUX);
   6930         }
   6931         if (!(camState & MM_CAMERA_TYPE_MAIN)) {
   6932             //Activate Main
   6933             camState |= MM_CAMERA_TYPE_MAIN;
   6934         }
   6935     } else if (zoomLevel > 60) {
   6936         //TELE Zone
   6937         LOGH("TELE ZONE : %d and  %d", zoomLevel, prev_zoomLevel);
   6938         if (!(camState & MM_CAMERA_TYPE_AUX)) {
   6939             //Activate Aux
   6940             camState |= MM_CAMERA_TYPE_AUX;
   6941         }
   6942         if (camState & MM_CAMERA_TYPE_MAIN) {
   6943             //Suspend Main
   6944             camState &= (~MM_CAMERA_TYPE_MAIN);
   6945         }
   6946     } else {
   6947         //Dual Zone
   6948         LOGH("DUAL ZONE : %d and  %d", zoomLevel, prev_zoomLevel);
   6949         if (!(camState & MM_CAMERA_TYPE_AUX)) {
   6950             //Activate Aux
   6951             camState |= MM_CAMERA_TYPE_AUX;
   6952         }
   6953         if (!(camState & MM_CAMERA_TYPE_MAIN)) {
   6954             //Activate Main
   6955             camState |= MM_CAMERA_TYPE_MAIN;
   6956         }
   6957     }
   6958 
   6959     if (camState != 0 && camState != mActiveCamera) {
   6960         processCameraControl(camState);
   6961     }
   6962 
   6963     if (zoomLevel >= 40 && prev_zoomLevel < 40) {
   6964         //Switch camera
   6965         switchCameraCb();
   6966         prev_zoomLevel = zoomLevel;
   6967     } else if (prev_zoomLevel >= 40 && zoomLevel  < 40){
   6968        switchCameraCb();
   6969        prev_zoomLevel = zoomLevel;
   6970     }
   6971     return 0;
   6972 }
   6973 
   6974 /*===========================================================================
   6975  * FUNCTION   : processCameraControl
   6976  *
   6977  * DESCRIPTION: Suspend and resume camera
   6978  *
   6979  * PARAMETERS :
   6980  *
   6981  * RETURN     : int32_t type of status
   6982  *              NO_ERROR  -- success
   6983  *              none-zero failure code
   6984  *==========================================================================*/
   6985 int32_t QCamera2HardwareInterface::processCameraControl(uint32_t camState)
   6986 {
   6987     int32_t ret = NO_ERROR;
   6988 
   6989     //Set camera controls to parameter and back-end
   6990     ret = mParameters.setCameraControls(camState, TRUE);
   6991 
   6992     //Update camera status to internal channel
   6993     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   6994         if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
   6995             ret = m_channels[i]->processCameraControl(camState);
   6996             if (ret != NO_ERROR) {
   6997                 LOGE("Channel Switch Failed");
   6998                 break;
   6999             }
   7000         }
   7001     }
   7002     if (ret == NO_ERROR) {
   7003         if (camState == MM_CAMERA_TYPE_MAIN) {
   7004             m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle);
   7005         } else if (camState == MM_CAMERA_TYPE_AUX) {
   7006             m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle);
   7007         }
   7008     }
   7009     LOGH("mActiveCamera = %d to %d", mActiveCamera, camState);
   7010     mActiveCamera = camState;
   7011     return ret;
   7012 }
   7013 
   7014 /*===========================================================================
   7015  * FUNCTION   : switchCameraCb
   7016  *
   7017  * DESCRIPTION: switch camera's in case of dual camera
   7018  *
   7019  * PARAMETERS :
   7020  *
   7021  * RETURN     : int32_t type of status
   7022  *              NO_ERROR  -- success
   7023  *              none-zero failure code
   7024  *==========================================================================*/
   7025 int32_t QCamera2HardwareInterface::switchCameraCb()
   7026 {
   7027     int32_t ret = NO_ERROR;
   7028 
   7029     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   7030         if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
   7031             ret = m_channels[i]->switchChannelCb();
   7032             if (ret != NO_ERROR) {
   7033                 LOGE("Channel Switch Failed");
   7034                 break;
   7035             }
   7036         }
   7037     }
   7038     if (ret == NO_ERROR && mActiveCamera == MM_CAMERA_DUAL_CAM) {
   7039         if (get_aux_camera_handle(mCameraHandle->camera_handle)
   7040                 == m_ActiveHandle) {
   7041             m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle);
   7042         } else if (get_main_camera_handle(mCameraHandle->camera_handle)
   7043                 == m_ActiveHandle) {
   7044             m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle);
   7045         } else {
   7046             m_ActiveHandle = mCameraHandle->camera_handle;
   7047         }
   7048     }
   7049     return ret;
   7050 }
   7051 
   7052 /*===========================================================================
   7053  * FUNCTION   : lockAPI
   7054  *
   7055  * DESCRIPTION: lock to process API
   7056  *
   7057  * PARAMETERS : none
   7058  *
   7059  * RETURN     : none
   7060  *==========================================================================*/
   7061 void QCamera2HardwareInterface::lockAPI()
   7062 {
   7063     pthread_mutex_lock(&m_lock);
   7064 }
   7065 
   7066 /*===========================================================================
   7067  * FUNCTION   : waitAPIResult
   7068  *
   7069  * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
   7070  *              return only cerntain API event type arrives
   7071  *
   7072  * PARAMETERS :
   7073  *   @api_evt : API event type
   7074  *
   7075  * RETURN     : none
   7076  *==========================================================================*/
   7077 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
   7078         qcamera_api_result_t *apiResult)
   7079 {
   7080     LOGD("wait for API result of evt (%d)", api_evt);
   7081     int resultReceived = 0;
   7082     while  (!resultReceived) {
   7083         pthread_cond_wait(&m_cond, &m_lock);
   7084         if (m_apiResultList != NULL) {
   7085             api_result_list *apiResultList = m_apiResultList;
   7086             api_result_list *apiResultListPrevious = m_apiResultList;
   7087             while (apiResultList != NULL) {
   7088                 if (apiResultList->result.request_api == api_evt) {
   7089                     resultReceived = 1;
   7090                     *apiResult = apiResultList->result;
   7091                     apiResultListPrevious->next = apiResultList->next;
   7092                     if (apiResultList == m_apiResultList) {
   7093                         m_apiResultList = apiResultList->next;
   7094                     }
   7095                     free(apiResultList);
   7096                     break;
   7097                 }
   7098                 else {
   7099                     apiResultListPrevious = apiResultList;
   7100                     apiResultList = apiResultList->next;
   7101                 }
   7102             }
   7103         }
   7104     }
   7105     LOGD("return (%d) from API result wait for evt (%d)",
   7106            apiResult->status, api_evt);
   7107 }
   7108 
   7109 
   7110 /*===========================================================================
   7111  * FUNCTION   : unlockAPI
   7112  *
   7113  * DESCRIPTION: API processing is done, unlock
   7114  *
   7115  * PARAMETERS : none
   7116  *
   7117  * RETURN     : none
   7118  *==========================================================================*/
   7119 void QCamera2HardwareInterface::unlockAPI()
   7120 {
   7121     pthread_mutex_unlock(&m_lock);
   7122 }
   7123 
   7124 /*===========================================================================
   7125  * FUNCTION   : signalAPIResult
   7126  *
   7127  * DESCRIPTION: signal condition viarable that cerntain API event type arrives
   7128  *
   7129  * PARAMETERS :
   7130  *   @result  : API result
   7131  *
   7132  * RETURN     : none
   7133  *==========================================================================*/
   7134 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
   7135 {
   7136 
   7137     pthread_mutex_lock(&m_lock);
   7138     api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
   7139     if (apiResult == NULL) {
   7140         LOGE("ERROR: malloc for api result failed, Result will not be sent");
   7141         goto malloc_failed;
   7142     }
   7143     apiResult->result = *result;
   7144     apiResult->next = NULL;
   7145     if (m_apiResultList == NULL) m_apiResultList = apiResult;
   7146     else {
   7147         api_result_list *apiResultList = m_apiResultList;
   7148         while(apiResultList->next != NULL) apiResultList = apiResultList->next;
   7149         apiResultList->next = apiResult;
   7150     }
   7151 malloc_failed:
   7152     pthread_cond_broadcast(&m_cond);
   7153     pthread_mutex_unlock(&m_lock);
   7154 }
   7155 
   7156 /*===========================================================================
   7157  * FUNCTION   : signalEvtResult
   7158  *
   7159  * DESCRIPTION: signal condition variable that certain event was processed
   7160  *
   7161  * PARAMETERS :
   7162  *   @result  : Event result
   7163  *
   7164  * RETURN     : none
   7165  *==========================================================================*/
   7166 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
   7167 {
   7168     pthread_mutex_lock(&m_evtLock);
   7169     m_evtResult = *result;
   7170     pthread_cond_signal(&m_evtCond);
   7171     pthread_mutex_unlock(&m_evtLock);
   7172 }
   7173 
   7174 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
   7175 {
   7176     int32_t rc = NO_ERROR;
   7177     cam_dimension_t str_dim,max_dim;
   7178     QCameraChannel *pChannel;
   7179 
   7180     max_dim.width = 0;
   7181     max_dim.height = 0;
   7182 
   7183     for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
   7184         if (m_channels[j] != NULL) {
   7185             pChannel = m_channels[j];
   7186             for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
   7187                 QCameraStream *pStream = pChannel->getStreamByIndex(i);
   7188                 if (pStream != NULL) {
   7189                     if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
   7190                             || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
   7191                         continue;
   7192                     }
   7193                     pStream->getFrameDimension(str_dim);
   7194                     if (str_dim.width > max_dim.width) {
   7195                         max_dim.width = str_dim.width;
   7196                     }
   7197                     if (str_dim.height > max_dim.height) {
   7198                         max_dim.height = str_dim.height;
   7199                     }
   7200                 }
   7201             }
   7202         }
   7203     }
   7204 
   7205     for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
   7206         QCameraStream *pStream = curChannel->getStreamByIndex(i);
   7207         if (pStream != NULL) {
   7208             if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
   7209                     || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
   7210                 continue;
   7211             }
   7212             pStream->getFrameDimension(str_dim);
   7213             if (str_dim.width > max_dim.width) {
   7214                 max_dim.width = str_dim.width;
   7215             }
   7216             if (str_dim.height > max_dim.height) {
   7217                 max_dim.height = str_dim.height;
   7218             }
   7219         }
   7220     }
   7221     rc = mParameters.updateRAW(max_dim);
   7222     return rc;
   7223 }
   7224 
   7225 /*===========================================================================
   7226  * FUNCTION   : addStreamToChannel
   7227  *
   7228  * DESCRIPTION: add a stream into a channel
   7229  *
   7230  * PARAMETERS :
   7231  *   @pChannel   : ptr to channel obj
   7232  *   @streamType : type of stream to be added
   7233  *   @streamCB   : callback of stream
   7234  *   @userData   : user data ptr to callback
   7235  *
   7236  * RETURN     : int32_t type of status
   7237  *              NO_ERROR  -- success
   7238  *              none-zero failure code
   7239  *==========================================================================*/
   7240 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
   7241                                                       cam_stream_type_t streamType,
   7242                                                       stream_cb_routine streamCB,
   7243                                                       void *userData)
   7244 {
   7245     int32_t rc = NO_ERROR;
   7246     QCameraHeapMemory *pStreamInfo = NULL;
   7247 
   7248     if (streamType == CAM_STREAM_TYPE_RAW) {
   7249         prepareRawStream(pChannel);
   7250     }
   7251 
   7252     pStreamInfo = allocateStreamInfoBuf(streamType, getStreamRefCount(streamType));
   7253     if (pStreamInfo == NULL) {
   7254         LOGE("no mem for stream info buf");
   7255         return NO_MEMORY;
   7256     }
   7257 
   7258     bool bDynAllocBuf = false;
   7259     if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
   7260         bDynAllocBuf = true;
   7261     }
   7262 
   7263     cam_padding_info_t padding_info;
   7264 
   7265     if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
   7266         cam_analysis_info_t analysisInfo;
   7267         cam_feature_mask_t featureMask;
   7268 
   7269         featureMask = 0;
   7270         mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask);
   7271         rc = mParameters.getAnalysisInfo(
   7272                 ((mParameters.getRecordingHintValue() == true) &&
   7273                  mParameters.fdModeInVideo()),
   7274                 FALSE,
   7275                 featureMask,
   7276                 &analysisInfo);
   7277         if (rc != NO_ERROR) {
   7278             LOGE("getAnalysisInfo failed, ret = %d", rc);
   7279             return rc;
   7280         }
   7281 
   7282         padding_info = analysisInfo.analysis_padding_info;
   7283     } else {
   7284         padding_info =
   7285                 gCamCapability[mCameraId]->padding_info;
   7286         if (streamType == CAM_STREAM_TYPE_PREVIEW) {
   7287             padding_info.width_padding = mSurfaceStridePadding;
   7288             padding_info.height_padding = CAM_PAD_TO_2;
   7289         }
   7290         if((!needReprocess())
   7291                 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
   7292                 || (!mParameters.isLLNoiseEnabled())) {
   7293             padding_info.offset_info.offset_x = 0;
   7294             padding_info.offset_info.offset_y = 0;
   7295         }
   7296     }
   7297 
   7298     bool deferAllocation = needDeferred(streamType);
   7299     LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
   7300             deferAllocation, bDynAllocBuf, streamType);
   7301     rc = pChannel->addStream(*this,
   7302             pStreamInfo,
   7303             NULL,
   7304             &padding_info,
   7305             streamCB, userData,
   7306             bDynAllocBuf,
   7307             deferAllocation);
   7308 
   7309     if (rc != NO_ERROR) {
   7310         LOGE("add stream type (%d) failed, ret = %d",
   7311                streamType, rc);
   7312         return rc;
   7313     }
   7314 
   7315     return rc;
   7316 }
   7317 
   7318 /*===========================================================================
   7319  * FUNCTION   : addPreviewChannel
   7320  *
   7321  * DESCRIPTION: add a preview channel that contains a preview stream
   7322  *
   7323  * PARAMETERS : none
   7324  *
   7325  * RETURN     : int32_t type of status
   7326  *              NO_ERROR  -- success
   7327  *              none-zero failure code
   7328  *==========================================================================*/
   7329 int32_t QCamera2HardwareInterface::addPreviewChannel()
   7330 {
   7331     int32_t rc = NO_ERROR;
   7332     QCameraChannel *pChannel = NULL;
   7333     char value[PROPERTY_VALUE_MAX];
   7334     bool raw_yuv = false;
   7335 
   7336 
   7337     if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
   7338         // if we had preview channel before, delete it first
   7339         delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
   7340         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
   7341     }
   7342 
   7343     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
   7344     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7345     if (NULL == pChannel) {
   7346         LOGE("no mem for preview channel");
   7347         return NO_MEMORY;
   7348     }
   7349 
   7350     // preview only channel, don't need bundle attr and cb
   7351     rc = pChannel->init(NULL, NULL, NULL);
   7352     if (rc != NO_ERROR) {
   7353         LOGE("init preview channel failed, ret = %d", rc);
   7354         return rc;
   7355     }
   7356 
   7357     // meta data stream always coexists with preview if applicable
   7358     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7359             metadata_stream_cb_routine, this);
   7360     if (rc != NO_ERROR) {
   7361         LOGE("add metadata stream failed, ret = %d", rc);
   7362         return rc;
   7363     }
   7364 
   7365     if (isRdiMode()) {
   7366         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   7367                 rdi_mode_stream_cb_routine, this);
   7368     } else {
   7369         if (isNoDisplayMode()) {
   7370             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7371                     nodisplay_preview_stream_cb_routine, this);
   7372         } else {
   7373             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7374                                     preview_stream_cb_routine, this);
   7375 #ifdef TARGET_TS_MAKEUP
   7376             int whiteLevel, cleanLevel;
   7377             if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
   7378 #endif
   7379             if (!isDualCamera()) {
   7380                 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   7381                         synchronous_stream_cb_routine);
   7382             }
   7383         }
   7384     }
   7385 
   7386     if (((mParameters.fdModeInVideo())
   7387             || (mParameters.getDcrf() == true)
   7388             || (mParameters.getRecordingHintValue() != true))
   7389             && (!mParameters.isSecureMode())) {
   7390         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   7391                 NULL, this);
   7392         if (rc != NO_ERROR) {
   7393             LOGE("add Analysis stream failed, ret = %d", rc);
   7394             return rc;
   7395         }
   7396     }
   7397 
   7398     property_get("persist.camera.raw_yuv", value, "0");
   7399     raw_yuv = atoi(value) > 0 ? true : false;
   7400     if ( raw_yuv ) {
   7401         rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
   7402                 preview_raw_stream_cb_routine,this);
   7403         if ( rc != NO_ERROR ) {
   7404             LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
   7405             delete pChannel;
   7406             return rc;
   7407         }
   7408     }
   7409 
   7410     if (rc != NO_ERROR) {
   7411         LOGE("add preview stream failed, ret = %d", rc);
   7412         delete pChannel;
   7413         return rc;
   7414     }
   7415 
   7416     m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
   7417     return rc;
   7418 }
   7419 
   7420 /*===========================================================================
   7421  * FUNCTION   : addVideoChannel
   7422  *
   7423  * DESCRIPTION: add a video channel that contains a video stream
   7424  *
   7425  * PARAMETERS : none
   7426  *
   7427  * RETURN     : int32_t type of status
   7428  *              NO_ERROR  -- success
   7429  *              none-zero failure code
   7430  *==========================================================================*/
   7431 int32_t QCamera2HardwareInterface::addVideoChannel()
   7432 {
   7433     int32_t rc = NO_ERROR;
   7434     QCameraVideoChannel *pChannel = NULL;
   7435 
   7436     if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
   7437         // if we had video channel before, delete it first
   7438         delete m_channels[QCAMERA_CH_TYPE_VIDEO];
   7439         m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
   7440     }
   7441 
   7442     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
   7443     pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
   7444     if (NULL == pChannel) {
   7445         LOGE("no mem for video channel");
   7446         return NO_MEMORY;
   7447     }
   7448 
   7449     if (isLowPowerMode()) {
   7450         mm_camera_channel_attr_t attr;
   7451         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7452         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7453         attr.look_back = 0; //wait for future frame for liveshot
   7454         attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7455         attr.water_mark = 1; //hold min buffers possible in Q
   7456         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7457         rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
   7458     } else {
   7459         // preview only channel, don't need bundle attr and cb
   7460         rc = pChannel->init(NULL, NULL, NULL);
   7461     }
   7462 
   7463     if (rc != 0) {
   7464         LOGE("init video channel failed, ret = %d", rc);
   7465         delete pChannel;
   7466         return rc;
   7467     }
   7468 
   7469     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
   7470             video_stream_cb_routine, this);
   7471 
   7472     if (rc != NO_ERROR) {
   7473         LOGE("add video stream failed, ret = %d", rc);
   7474         delete pChannel;
   7475         return rc;
   7476     }
   7477 
   7478     m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
   7479     return rc;
   7480 }
   7481 
   7482 /*===========================================================================
   7483  * FUNCTION   : addSnapshotChannel
   7484  *
   7485  * DESCRIPTION: add a snapshot channel that contains a snapshot stream
   7486  *
   7487  * PARAMETERS : none
   7488  *
   7489  * RETURN     : int32_t type of status
   7490  *              NO_ERROR  -- success
   7491  *              none-zero failure code
   7492  * NOTE       : Add this channel for live snapshot usecase. Regular capture will
   7493  *              use addCaptureChannel.
   7494  *==========================================================================*/
   7495 int32_t QCamera2HardwareInterface::addSnapshotChannel()
   7496 {
   7497     int32_t rc = NO_ERROR;
   7498     QCameraChannel *pChannel = NULL;
   7499 
   7500     if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
   7501         // if we had ZSL channel before, delete it first
   7502         delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
   7503         m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
   7504     }
   7505 
   7506     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   7507     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7508     if (NULL == pChannel) {
   7509         LOGE("no mem for snapshot channel");
   7510         return NO_MEMORY;
   7511     }
   7512 
   7513     mm_camera_channel_attr_t attr;
   7514     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7515     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   7516     attr.look_back = 0; //wait for future frame for liveshot
   7517     attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7518     attr.water_mark = 1; //hold min buffers possible in Q
   7519     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7520     attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
   7521     rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
   7522     if (rc != NO_ERROR) {
   7523         LOGE("init snapshot channel failed, ret = %d", rc);
   7524         delete pChannel;
   7525         return rc;
   7526     }
   7527 
   7528     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   7529             NULL, NULL);
   7530     if (rc != NO_ERROR) {
   7531         LOGE("add snapshot stream failed, ret = %d", rc);
   7532         delete pChannel;
   7533         return rc;
   7534     }
   7535 
   7536     m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
   7537     return rc;
   7538 }
   7539 
   7540 /*===========================================================================
   7541  * FUNCTION   : addRawChannel
   7542  *
   7543  * DESCRIPTION: add a raw channel that contains a raw image stream
   7544  *
   7545  * PARAMETERS : none
   7546  *
   7547  * RETURN     : int32_t type of status
   7548  *              NO_ERROR  -- success
   7549  *              none-zero failure code
   7550  *==========================================================================*/
   7551 int32_t QCamera2HardwareInterface::addRawChannel()
   7552 {
   7553     int32_t rc = NO_ERROR;
   7554     QCameraChannel *pChannel = NULL;
   7555 
   7556     if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
   7557         // if we had raw channel before, delete it first
   7558         delete m_channels[QCAMERA_CH_TYPE_RAW];
   7559         m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
   7560     }
   7561 
   7562     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
   7563     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7564     if (NULL == pChannel) {
   7565         LOGE("no mem for raw channel");
   7566         return NO_MEMORY;
   7567     }
   7568 
   7569     if (mParameters.getofflineRAW()) {
   7570         mm_camera_channel_attr_t attr;
   7571         memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7572         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7573         attr.look_back = mParameters.getZSLBackLookCount();
   7574         attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7575         attr.water_mark = 1;
   7576         attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7577         rc = pChannel->init(&attr, raw_channel_cb_routine, this);
   7578         if (rc != NO_ERROR) {
   7579             LOGE("init RAW channel failed, ret = %d", rc);
   7580             delete pChannel;
   7581             return rc;
   7582         }
   7583     } else {
   7584         rc = pChannel->init(NULL, NULL, NULL);
   7585         if (rc != NO_ERROR) {
   7586             LOGE("init raw channel failed, ret = %d", rc);
   7587             delete pChannel;
   7588             return rc;
   7589         }
   7590     }
   7591 
   7592     if (!mParameters.isZSLMode()) {
   7593         // meta data stream always coexists with snapshot in regular RAW capture case
   7594         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7595                 metadata_stream_cb_routine, this);
   7596         if (rc != NO_ERROR) {
   7597             LOGE("add metadata stream failed, ret = %d", rc);
   7598             delete pChannel;
   7599             return rc;
   7600         }
   7601     }
   7602 
   7603     if (mParameters.getofflineRAW()) {
   7604         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   7605                 NULL, this);
   7606     } else {
   7607         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
   7608                 raw_stream_cb_routine, this);
   7609     }
   7610     if (rc != NO_ERROR) {
   7611         LOGE("add snapshot stream failed, ret = %d", rc);
   7612         delete pChannel;
   7613         return rc;
   7614     }
   7615     m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
   7616     return rc;
   7617 }
   7618 
   7619 /*===========================================================================
   7620  * FUNCTION   : addZSLChannel
   7621  *
   7622  * DESCRIPTION: add a ZSL channel that contains a preview stream and
   7623  *              a snapshot stream
   7624  *
   7625  * PARAMETERS : none
   7626  *
   7627  * RETURN     : int32_t type of status
   7628  *              NO_ERROR  -- success
   7629  *              none-zero failure code
   7630  *==========================================================================*/
   7631 int32_t QCamera2HardwareInterface::addZSLChannel()
   7632 {
   7633     int32_t rc = NO_ERROR;
   7634     QCameraPicChannel *pChannel = NULL;
   7635     char value[PROPERTY_VALUE_MAX];
   7636     bool raw_yuv = false;
   7637 
   7638     if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
   7639         // if we had ZSL channel before, delete it first
   7640         delete m_channels[QCAMERA_CH_TYPE_ZSL];
   7641         m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
   7642     }
   7643 
   7644     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
   7645     pChannel = new QCameraPicChannel(handle,
   7646                                      mCameraHandle->ops);
   7647     if (NULL == pChannel) {
   7648         LOGE("no mem for ZSL channel");
   7649         return NO_MEMORY;
   7650     }
   7651 
   7652     // ZSL channel, init with bundle attr and cb
   7653     mm_camera_channel_attr_t attr;
   7654     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7655     if (mParameters.isSceneSelectionEnabled()) {
   7656         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   7657     } else {
   7658         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7659     }
   7660     attr.look_back = mParameters.getZSLBackLookCount();
   7661     attr.post_frame_skip = mParameters.getZSLBurstInterval();
   7662     if (mParameters.isOEMFeatEnabled()) {
   7663         attr.post_frame_skip++;
   7664     }
   7665     attr.water_mark = mParameters.getZSLQueueDepth();
   7666     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7667     attr.user_expected_frame_id =
   7668         mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
   7669 
   7670     //Enabled matched queue
   7671     if (isFrameSyncEnabled()) {
   7672         LOGH("Enabling frame sync for dual camera, camera Id: %d",
   7673                  mCameraId);
   7674         attr.enable_frame_sync = 1;
   7675     }
   7676     rc = pChannel->init(&attr,
   7677                         zsl_channel_cb,
   7678                         this);
   7679     if (rc != 0) {
   7680         LOGE("init ZSL channel failed, ret = %d", rc);
   7681         delete pChannel;
   7682         return rc;
   7683     }
   7684 
   7685     // meta data stream always coexists with preview if applicable
   7686     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7687             metadata_stream_cb_routine, this);
   7688     if (rc != NO_ERROR) {
   7689         LOGE("add metadata stream failed, ret = %d", rc);
   7690         delete pChannel;
   7691         return rc;
   7692     }
   7693 
   7694     if (isNoDisplayMode()) {
   7695         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7696                 nodisplay_preview_stream_cb_routine, this);
   7697     } else {
   7698         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7699                                 preview_stream_cb_routine, this);
   7700 #ifdef TARGET_TS_MAKEUP
   7701         int whiteLevel, cleanLevel;
   7702         if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
   7703 #endif
   7704         if (!isDualCamera()) {
   7705             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   7706                     synchronous_stream_cb_routine);
   7707         }
   7708     }
   7709     if (rc != NO_ERROR) {
   7710         LOGE("add preview stream failed, ret = %d", rc);
   7711         delete pChannel;
   7712         return rc;
   7713     }
   7714 
   7715     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   7716             NULL, this);
   7717     if (rc != NO_ERROR) {
   7718         LOGE("add snapshot stream failed, ret = %d", rc);
   7719         delete pChannel;
   7720         return rc;
   7721     }
   7722 
   7723     if (!mParameters.isSecureMode()) {
   7724         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   7725                 NULL, this);
   7726         if (rc != NO_ERROR) {
   7727             LOGE("add Analysis stream failed, ret = %d", rc);
   7728             delete pChannel;
   7729             return rc;
   7730         }
   7731     }
   7732 
   7733     property_get("persist.camera.raw_yuv", value, "0");
   7734     raw_yuv = atoi(value) > 0 ? true : false;
   7735     if (raw_yuv) {
   7736         rc = addStreamToChannel(pChannel,
   7737                                 CAM_STREAM_TYPE_RAW,
   7738                                 preview_raw_stream_cb_routine,
   7739                                 this);
   7740         if (rc != NO_ERROR) {
   7741             LOGE("add raw stream failed, ret = %d", rc);
   7742             delete pChannel;
   7743             return rc;
   7744         }
   7745     }
   7746 
   7747     m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
   7748     return rc;
   7749 }
   7750 
   7751 /*===========================================================================
   7752  * FUNCTION   : addCaptureChannel
   7753  *
   7754  * DESCRIPTION: add a capture channel that contains a snapshot stream
   7755  *              and a postview stream
   7756  *
   7757  * PARAMETERS : none
   7758  *
   7759  * RETURN     : int32_t type of status
   7760  *              NO_ERROR  -- success
   7761  *              none-zero failure code
   7762  * NOTE       : Add this channel for regular capture usecase.
   7763  *              For Live snapshot usecase, use addSnapshotChannel.
   7764  *==========================================================================*/
   7765 int32_t QCamera2HardwareInterface::addCaptureChannel()
   7766 {
   7767     int32_t rc = NO_ERROR;
   7768     QCameraPicChannel *pChannel = NULL;
   7769     char value[PROPERTY_VALUE_MAX];
   7770     bool raw_yuv = false;
   7771 
   7772     if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
   7773         delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
   7774         m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
   7775     }
   7776 
   7777     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
   7778     pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
   7779     if (NULL == pChannel) {
   7780         LOGE("no mem for capture channel");
   7781         return NO_MEMORY;
   7782     }
   7783 
   7784     // Capture channel, only need snapshot and postview streams start together
   7785     mm_camera_channel_attr_t attr;
   7786     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   7787     if ( mLongshotEnabled ) {
   7788         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
   7789         attr.look_back = mParameters.getZSLBackLookCount();
   7790         attr.water_mark = mParameters.getZSLQueueDepth();
   7791     } else {
   7792         attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   7793     }
   7794     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   7795 
   7796     rc = pChannel->init(&attr,
   7797                         capture_channel_cb_routine,
   7798                         this);
   7799     if (rc != NO_ERROR) {
   7800         LOGE("init capture channel failed, ret = %d", rc);
   7801         return rc;
   7802     }
   7803 
   7804     // meta data stream always coexists with snapshot in regular capture case
   7805     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7806             metadata_stream_cb_routine, this);
   7807     if (rc != NO_ERROR) {
   7808         LOGE("add metadata stream failed, ret = %d", rc);
   7809         return rc;
   7810     }
   7811 
   7812     if (mLongshotEnabled) {
   7813         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
   7814                 preview_stream_cb_routine, this);
   7815         if (rc != NO_ERROR) {
   7816             LOGE("add preview stream failed, ret = %d", rc);
   7817             return rc;
   7818         }
   7819 #ifdef TARGET_TS_MAKEUP
   7820         int whiteLevel, cleanLevel;
   7821         if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
   7822 #endif
   7823         if (!isDualCamera()) {
   7824             pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
   7825                     synchronous_stream_cb_routine);
   7826         }
   7827     //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
   7828     } else if (!mParameters.getQuadraCfa()) {
   7829         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
   7830                                 NULL, this);
   7831         if (rc != NO_ERROR) {
   7832             LOGE("add postview stream failed, ret = %d", rc);
   7833             return rc;
   7834         }
   7835     }
   7836 
   7837     if (!mParameters.getofflineRAW()) {
   7838         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
   7839                 NULL, this);
   7840         if (rc != NO_ERROR) {
   7841             LOGE("add snapshot stream failed, ret = %d", rc);
   7842             return rc;
   7843         }
   7844     }
   7845 
   7846     stream_cb_routine stream_cb = NULL;
   7847     property_get("persist.camera.raw_yuv", value, "0");
   7848     raw_yuv = atoi(value) > 0 ? true : false;
   7849 
   7850     if (raw_yuv) {
   7851         stream_cb = snapshot_raw_stream_cb_routine;
   7852     }
   7853 
   7854     if ((raw_yuv) || (mParameters.getofflineRAW())) {
   7855         rc = addStreamToChannel(pChannel,
   7856                 CAM_STREAM_TYPE_RAW, stream_cb, this);
   7857         if (rc != NO_ERROR) {
   7858             LOGE("add raw stream failed, ret = %d", rc);
   7859             return rc;
   7860         }
   7861     }
   7862 
   7863     m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
   7864     return rc;
   7865 }
   7866 
   7867 /*===========================================================================
   7868  * FUNCTION   : addMetaDataChannel
   7869  *
   7870  * DESCRIPTION: add a meta data channel that contains a metadata stream
   7871  *
   7872  * PARAMETERS : none
   7873  *
   7874  * RETURN     : int32_t type of status
   7875  *              NO_ERROR  -- success
   7876  *              none-zero failure code
   7877  *==========================================================================*/
   7878 int32_t QCamera2HardwareInterface::addMetaDataChannel()
   7879 {
   7880     int32_t rc = NO_ERROR;
   7881     QCameraChannel *pChannel = NULL;
   7882 
   7883     if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
   7884         delete m_channels[QCAMERA_CH_TYPE_METADATA];
   7885         m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
   7886     }
   7887 
   7888     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
   7889     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7890     if (NULL == pChannel) {
   7891         LOGE("no mem for metadata channel");
   7892         return NO_MEMORY;
   7893     }
   7894 
   7895     rc = pChannel->init(NULL,
   7896                         NULL,
   7897                         NULL);
   7898     if (rc != NO_ERROR) {
   7899         LOGE("init metadata channel failed, ret = %d", rc);
   7900         delete pChannel;
   7901         return rc;
   7902     }
   7903 
   7904     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
   7905             metadata_stream_cb_routine, this);
   7906     if (rc != NO_ERROR) {
   7907         LOGE("add metadata stream failed, ret = %d", rc);
   7908         delete pChannel;
   7909         return rc;
   7910     }
   7911 
   7912     m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
   7913     return rc;
   7914 }
   7915 
   7916 /*===========================================================================
   7917  * FUNCTION   : addCallbackChannel
   7918  *
   7919  * DESCRIPTION: add a callback channel that contains a callback stream
   7920  *
   7921  * PARAMETERS : none
   7922  *
   7923  * RETURN     : int32_t type of status
   7924  *              NO_ERROR  -- success
   7925  *              none-zero failure code
   7926  *==========================================================================*/
   7927 int32_t QCamera2HardwareInterface::addCallbackChannel()
   7928 {
   7929     int32_t rc = NO_ERROR;
   7930     QCameraChannel *pChannel = NULL;
   7931 
   7932     if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
   7933         delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
   7934         m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
   7935     }
   7936 
   7937     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
   7938     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7939     if (NULL == pChannel) {
   7940         LOGE("no mem for callback channel");
   7941         return NO_MEMORY;
   7942     }
   7943 
   7944     rc = pChannel->init(NULL, NULL, this);
   7945     if (rc != NO_ERROR) {
   7946         LOGE("init callback channel failed, ret = %d",
   7947                  rc);
   7948         delete pChannel;
   7949         return rc;
   7950     }
   7951 
   7952     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
   7953             callback_stream_cb_routine, this);
   7954     if (rc != NO_ERROR) {
   7955         LOGE("add callback stream failed, ret = %d", rc);
   7956         delete pChannel;
   7957         return rc;
   7958     }
   7959 
   7960     m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
   7961     return rc;
   7962 }
   7963 
   7964 
   7965 /*===========================================================================
   7966  * FUNCTION   : addAnalysisChannel
   7967  *
   7968  * DESCRIPTION: add a analysis channel that contains a analysis stream
   7969  *
   7970  * PARAMETERS : none
   7971  *
   7972  * RETURN     : int32_t type of status
   7973  *              NO_ERROR  -- success
   7974  *              none-zero failure code
   7975  *==========================================================================*/
   7976 int32_t QCamera2HardwareInterface::addAnalysisChannel()
   7977 {
   7978     int32_t rc = NO_ERROR;
   7979     QCameraChannel *pChannel = NULL;
   7980 
   7981     if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
   7982         delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
   7983         m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
   7984     }
   7985 
   7986     uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
   7987     pChannel = new QCameraChannel(handle, mCameraHandle->ops);
   7988     if (NULL == pChannel) {
   7989         LOGE("no mem for metadata channel");
   7990         return NO_MEMORY;
   7991     }
   7992 
   7993     rc = pChannel->init(NULL, NULL, this);
   7994     if (rc != NO_ERROR) {
   7995         LOGE("init Analysis channel failed, ret = %d", rc);
   7996         delete pChannel;
   7997         return rc;
   7998     }
   7999 
   8000     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
   8001             NULL, this);
   8002     if (rc != NO_ERROR) {
   8003         LOGE("add Analysis stream failed, ret = %d", rc);
   8004         delete pChannel;
   8005         return rc;
   8006     }
   8007 
   8008     m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
   8009     return rc;
   8010 }
   8011 
   8012 
   8013 /*===========================================================================
   8014  * FUNCTION   : getPPConfig
   8015  *
   8016  * DESCRIPTION: get Post processing configaration data
   8017  *
   8018  * PARAMETERS :
   8019  * @pp config:  pp config structure pointer,
   8020  * @curIndex:  current pp channel index
   8021  * @multipass: Flag if multipass prcessing enabled.
   8022  *
   8023  * RETURN     : int32_t type of status
   8024  *              NO_ERROR  -- success
   8025  *              none-zero failure code
   8026  *==========================================================================*/
   8027 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
   8028         int8_t curIndex, bool multipass)
   8029 {
   8030     int32_t rc = NO_ERROR;
   8031     int32_t feature_set = 0;
   8032 
   8033     if (multipass) {
   8034         LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
   8035                 mParameters.getReprocCount(), curIndex);
   8036     }
   8037 
   8038     LOGH("Supported pproc feature mask = %llx",
   8039             gCamCapability[mCameraId]->qcom_supported_feature_mask);
   8040     cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
   8041     int32_t zoomLevel = mParameters.getParmZoomLevel();
   8042     uint32_t rotation = mParameters.getJpegRotation();
   8043     int32_t effect = mParameters.getEffectValue();
   8044 
   8045     pp_config.cur_reproc_count = curIndex + 1;
   8046     pp_config.total_reproc_count = mParameters.getReprocCount();
   8047 
   8048     //Checking what feature mask to enable
   8049     if (curIndex == 0) {
   8050         if (mParameters.getQuadraCfa()) {
   8051             feature_set = 2;
   8052         } else {
   8053             feature_set = 0;
   8054         }
   8055     } else if (curIndex == 1) {
   8056         if (mParameters.getQuadraCfa()) {
   8057             feature_set = 0;
   8058         } else {
   8059             feature_set = 1;
   8060         }
   8061     }
   8062 
   8063     switch(feature_set) {
   8064         case 0:
   8065             //Configure feature mask for first pass of reprocessing
   8066             //check if any effects are enabled
   8067             if ((CAM_EFFECT_MODE_OFF != effect) &&
   8068                 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
   8069                 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
   8070                 pp_config.effect = effect;
   8071             }
   8072 
   8073             //check for features that need to be enabled by default like sharpness
   8074             //(if supported by hw).
   8075             if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
   8076                 !mParameters.isOptiZoomEnabled()) {
   8077                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
   8078                 pp_config.sharpness = mParameters.getSharpness();
   8079             }
   8080 
   8081             //check if zoom is enabled
   8082             if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
   8083                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   8084             }
   8085 
   8086             if (mParameters.isWNREnabled() &&
   8087                 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
   8088                 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
   8089                 pp_config.denoise2d.denoise_enable = 1;
   8090                 pp_config.denoise2d.process_plates =
   8091                         mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
   8092             }
   8093 
   8094             if (isCACEnabled()) {
   8095                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
   8096             }
   8097 
   8098             //check if rotation is required
   8099             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
   8100                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
   8101                 if (rotation == 0) {
   8102                     pp_config.rotation = ROTATE_0;
   8103                 } else if (rotation == 90) {
   8104                     pp_config.rotation = ROTATE_90;
   8105                 } else if (rotation == 180) {
   8106                     pp_config.rotation = ROTATE_180;
   8107                 } else if (rotation == 270) {
   8108                     pp_config.rotation = ROTATE_270;
   8109                 }
   8110             }
   8111 
   8112             if (mParameters.isHDREnabled()){
   8113                 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
   8114                 pp_config.hdr_param.hdr_enable = 1;
   8115                 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
   8116                 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
   8117             } else {
   8118                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
   8119                 pp_config.hdr_param.hdr_enable = 0;
   8120             }
   8121 
   8122             //check if scaling is enabled
   8123             if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
   8124                 mParameters.isReprocScaleEnabled() &&
   8125                 mParameters.isUnderReprocScaling()){
   8126                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   8127                 mParameters.getPicSizeFromAPK(
   8128                         pp_config.scale_param.output_width,
   8129                         pp_config.scale_param.output_height);
   8130             }
   8131 
   8132             if(mParameters.isUbiFocusEnabled()) {
   8133                 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
   8134             } else {
   8135                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
   8136             }
   8137 
   8138             if(mParameters.isUbiRefocus()) {
   8139                 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
   8140                 pp_config.misc_buf_param.misc_buffer_index = 0;
   8141             } else {
   8142                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
   8143             }
   8144 
   8145             if(mParameters.isChromaFlashEnabled()) {
   8146                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
   8147                 pp_config.flash_value = CAM_FLASH_ON;
   8148             } else {
   8149                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
   8150             }
   8151 
   8152             if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
   8153                 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
   8154                 pp_config.zoom_level = (uint8_t) zoomLevel;
   8155             } else {
   8156                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
   8157             }
   8158 
   8159             if (mParameters.getofflineRAW()) {
   8160                 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
   8161             }
   8162 
   8163             if (mParameters.isTruePortraitEnabled()) {
   8164                 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
   8165                 pp_config.misc_buf_param.misc_buffer_index = 0;
   8166             } else {
   8167                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
   8168             }
   8169 
   8170             if(mParameters.isStillMoreEnabled()) {
   8171                 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
   8172             } else {
   8173                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
   8174             }
   8175 
   8176             if (mParameters.isOEMFeatEnabled()) {
   8177                 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
   8178             }
   8179 
   8180             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
   8181                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
   8182                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
   8183                 } else {
   8184                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
   8185                 }
   8186             }
   8187 
   8188             if ((multipass) &&
   8189                     (m_postprocessor.getPPChannelCount() > 1)
   8190                     && (!mParameters.getQuadraCfa())) {
   8191                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
   8192                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
   8193                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
   8194                 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
   8195                 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   8196             } else {
   8197                 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
   8198             }
   8199 
   8200             cam_dimension_t thumb_src_dim;
   8201             cam_dimension_t thumb_dst_dim;
   8202             mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
   8203             mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
   8204             if ((thumb_dst_dim.width != thumb_src_dim.width) ||
   8205                     (thumb_dst_dim.height != thumb_src_dim.height)) {
   8206                 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
   8207                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
   8208                 }
   8209             }
   8210 
   8211             break;
   8212 
   8213         case 1:
   8214             //Configure feature mask for second pass of reprocessing
   8215             pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
   8216             if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
   8217                 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
   8218                 if (rotation == 0) {
   8219                     pp_config.rotation = ROTATE_0;
   8220                 } else if (rotation == 90) {
   8221                     pp_config.rotation = ROTATE_90;
   8222                 } else if (rotation == 180) {
   8223                     pp_config.rotation = ROTATE_180;
   8224                 } else if (rotation == 270) {
   8225                     pp_config.rotation = ROTATE_270;
   8226                 }
   8227             }
   8228             if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
   8229                 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
   8230                     pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
   8231                 } else {
   8232                     pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
   8233                 }
   8234             }
   8235             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
   8236             pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
   8237             break;
   8238 
   8239         case 2:
   8240             //Setting feature for Quadra CFA
   8241             pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
   8242             break;
   8243 
   8244     }
   8245 
   8246     LOGH("pproc feature mask set = %llx pass count = %d",
   8247         pp_config.feature_mask, curIndex);
   8248     return rc;
   8249 }
   8250 
   8251 /*===========================================================================
   8252  * FUNCTION   : addReprocChannel
   8253  *
   8254  * DESCRIPTION: add a reprocess channel that will do reprocess on frames
   8255  *              coming from input channel
   8256  *
   8257  * PARAMETERS :
   8258  *   @pInputChannel : ptr to input channel whose frames will be post-processed
   8259  *   @cur_channel_index : Current channel index in multipass
   8260  *
   8261  * RETURN     : Ptr to the newly created channel obj. NULL if failed.
   8262  *==========================================================================*/
   8263 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
   8264         QCameraChannel *pInputChannel, int8_t cur_channel_index)
   8265 {
   8266     int32_t rc = NO_ERROR;
   8267     QCameraReprocessChannel *pChannel = NULL;
   8268     uint32_t burst_cnt = mParameters.getNumOfSnapshots();
   8269     uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);
   8270 
   8271     if (pInputChannel == NULL) {
   8272         LOGE("input channel obj is NULL");
   8273         return NULL;
   8274     }
   8275 
   8276     pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
   8277     if (NULL == pChannel) {
   8278         LOGE("no mem for reprocess channel");
   8279         return NULL;
   8280     }
   8281 
   8282     // Capture channel, only need snapshot and postview streams start together
   8283     mm_camera_channel_attr_t attr;
   8284     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
   8285     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
   8286     attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
   8287     rc = pChannel->init(&attr,
   8288                         postproc_channel_cb_routine,
   8289                         this);
   8290     if (rc != NO_ERROR) {
   8291         LOGE("init reprocess channel failed, ret = %d", rc);
   8292         delete pChannel;
   8293         return NULL;
   8294     }
   8295 
   8296     // pp feature config
   8297     cam_pp_feature_config_t pp_config;
   8298     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
   8299 
   8300     rc = getPPConfig(pp_config, cur_channel_index,
   8301             ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
   8302     if (rc != NO_ERROR){
   8303         LOGE("Error while creating PP config");
   8304         delete pChannel;
   8305         return NULL;
   8306     }
   8307 
   8308     uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
   8309 
   8310     //WNR and HDR happen inline. No extra buffers needed.
   8311     cam_feature_mask_t temp_feature_mask = pp_config.feature_mask;
   8312     temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
   8313     if (temp_feature_mask && mParameters.isHDREnabled()) {
   8314         minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
   8315     }
   8316 
   8317     if (mParameters.isStillMoreEnabled()) {
   8318         cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
   8319         pp_config.burst_cnt = stillmore_config.burst_count;
   8320         LOGH("Stillmore burst %d", pp_config.burst_cnt);
   8321 
   8322         // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
   8323         // number of capture is already added. In the case of liveshot,
   8324         // stillmore burst is 1. This is to account for the premature decrement
   8325         if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
   8326             minStreamBufNum += 1;
   8327         }
   8328     }
   8329 
   8330     if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
   8331         minStreamBufNum += mParameters.getReprocCount() - 1;
   8332         burst_cnt = mParameters.getReprocCount();
   8333         if (cur_channel_index == 0) {
   8334             pChannel->setReprocCount(2);
   8335         } else {
   8336             pChannel->setReprocCount(1);
   8337         }
   8338     } else {
   8339         pChannel->setReprocCount(1);
   8340     }
   8341 
   8342 #ifdef DUAL_CAM_TEST //Temporary macro. Added to simulate B+B snapshot. Will be removed
   8343     if (isDualCamera()) {
   8344         minStreamBufNum += 1;
   8345     }
   8346 #endif
   8347     // Add non inplace image lib buffers only when ppproc is present,
   8348     // becuase pproc is non inplace and input buffers for img lib
   8349     // are output for pproc and this number of extra buffers is required
   8350     // If pproc is not there, input buffers for imglib are from snapshot stream
   8351     uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
   8352     if (temp_feature_mask && imglib_extra_bufs) {
   8353         // 1 is added because getNumOfExtraBuffersForImageProc returns extra
   8354         // buffers assuming number of capture is already added
   8355         minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
   8356     }
   8357 
   8358     //Mask out features that are already processed in snapshot stream.
   8359     cam_feature_mask_t snapshot_feature_mask = 0;
   8360     mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
   8361 
   8362     pp_config.feature_mask &= ~snapshot_feature_mask;
   8363     LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
   8364             snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);
   8365 
   8366     bool offlineReproc = needOfflineReprocessing();
   8367     if (m_postprocessor.mOfflineDataBufs != NULL) {
   8368         offlineReproc = TRUE;
   8369     }
   8370 
   8371     cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
   8372     paddingInfo.offset_info.offset_x = 0;
   8373     paddingInfo.offset_info.offset_y = 0;
   8374     rc = pChannel->addReprocStreamsFromSource(*this,
   8375                                               pp_config,
   8376                                               pInputChannel,
   8377                                               minStreamBufNum,
   8378                                               burst_cnt,
   8379                                               &paddingInfo,
   8380                                               mParameters,
   8381                                               mLongshotEnabled,
   8382                                               offlineReproc);
   8383     if (rc != NO_ERROR) {
   8384         delete pChannel;
   8385         return NULL;
   8386     }
   8387 
   8388     return pChannel;
   8389 }
   8390 
   8391 /*===========================================================================
   8392  * FUNCTION   : addOfflineReprocChannel
   8393  *
   8394  * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
   8395  *              that will do reprocess on frames coming from external images
   8396  *
   8397  * PARAMETERS :
   8398  *   @img_config  : offline reporcess image info
   8399  *   @pp_feature  : pp feature config
   8400  *
   8401  * RETURN     : int32_t type of status
   8402  *              NO_ERROR  -- success
   8403  *              none-zero failure code
   8404  *==========================================================================*/
   8405 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
   8406                                             cam_pp_offline_src_config_t &img_config,
   8407                                             cam_pp_feature_config_t &pp_feature,
   8408                                             stream_cb_routine stream_cb,
   8409                                             void *userdata)
   8410 {
   8411     int32_t rc = NO_ERROR;
   8412     QCameraReprocessChannel *pChannel = NULL;
   8413 
   8414     pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
   8415                                            mCameraHandle->ops);
   8416     if (NULL == pChannel) {
   8417         LOGE("no mem for reprocess channel");
   8418         return NULL;
   8419     }
   8420 
   8421     rc = pChannel->init(NULL, NULL, NULL);
   8422     if (rc != NO_ERROR) {
   8423         LOGE("init reprocess channel failed, ret = %d", rc);
   8424         delete pChannel;
   8425         return NULL;
   8426     }
   8427 
   8428     QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
   8429     if (pStreamInfo == NULL) {
   8430         LOGE("no mem for stream info buf");
   8431         delete pChannel;
   8432         return NULL;
   8433     }
   8434 
   8435     cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
   8436     memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
   8437     streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
   8438     streamInfoBuf->fmt = img_config.input_fmt;
   8439     streamInfoBuf->dim = img_config.input_dim;
   8440     streamInfoBuf->buf_planes = img_config.input_buf_planes;
   8441     streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
   8442     streamInfoBuf->num_of_burst = img_config.num_of_bufs;
   8443 
   8444     streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
   8445     streamInfoBuf->reprocess_config.offline = img_config;
   8446     streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
   8447     streamInfoBuf->num_bufs = img_config.num_of_bufs;
   8448 
   8449     rc = pChannel->addStream(*this,
   8450             pStreamInfo, NULL,
   8451             &gCamCapability[mCameraId]->padding_info,
   8452             stream_cb, userdata, false);
   8453 
   8454     if (rc != NO_ERROR) {
   8455         LOGE("add reprocess stream failed, ret = %d", rc);
   8456         delete pChannel;
   8457         return NULL;
   8458     }
   8459 
   8460     return pChannel;
   8461 }
   8462 
   8463 /*===========================================================================
   8464  * FUNCTION   : addChannel
   8465  *
   8466  * DESCRIPTION: add a channel by its type
   8467  *
   8468  * PARAMETERS :
   8469  *   @ch_type : channel type
   8470  *
   8471  * RETURN     : int32_t type of status
   8472  *              NO_ERROR  -- success
   8473  *              none-zero failure code
   8474  *==========================================================================*/
   8475 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
   8476 {
   8477     int32_t rc = UNKNOWN_ERROR;
   8478     switch (ch_type) {
   8479     case QCAMERA_CH_TYPE_ZSL:
   8480         rc = addZSLChannel();
   8481         break;
   8482     case QCAMERA_CH_TYPE_CAPTURE:
   8483         rc = addCaptureChannel();
   8484         break;
   8485     case QCAMERA_CH_TYPE_PREVIEW:
   8486         rc = addPreviewChannel();
   8487         break;
   8488     case QCAMERA_CH_TYPE_VIDEO:
   8489         rc = addVideoChannel();
   8490         break;
   8491     case QCAMERA_CH_TYPE_SNAPSHOT:
   8492         rc = addSnapshotChannel();
   8493         break;
   8494     case QCAMERA_CH_TYPE_RAW:
   8495         rc = addRawChannel();
   8496         break;
   8497     case QCAMERA_CH_TYPE_METADATA:
   8498         rc = addMetaDataChannel();
   8499         break;
   8500     case QCAMERA_CH_TYPE_CALLBACK:
   8501         rc = addCallbackChannel();
   8502         break;
   8503     case QCAMERA_CH_TYPE_ANALYSIS:
   8504         rc = addAnalysisChannel();
   8505         break;
   8506     default:
   8507         break;
   8508     }
   8509     return rc;
   8510 }
   8511 
   8512 /*===========================================================================
   8513  * FUNCTION   : delChannel
   8514  *
   8515  * DESCRIPTION: delete a channel by its type
   8516  *
   8517  * PARAMETERS :
   8518  *   @ch_type : channel type
   8519  *   @destroy : delete context as well
   8520  *
   8521  * RETURN     : int32_t type of status
   8522  *              NO_ERROR  -- success
   8523  *              none-zero failure code
   8524  *==========================================================================*/
   8525 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
   8526                                               bool destroy)
   8527 {
   8528     if (m_channels[ch_type] != NULL) {
   8529         if (destroy) {
   8530             delete m_channels[ch_type];
   8531             m_channels[ch_type] = NULL;
   8532         } else {
   8533             m_channels[ch_type]->deleteChannel();
   8534         }
   8535     }
   8536 
   8537     return NO_ERROR;
   8538 }
   8539 
   8540 /*===========================================================================
   8541  * FUNCTION   : startChannel
   8542  *
   8543  * DESCRIPTION: start a channel by its type
   8544  *
   8545  * PARAMETERS :
   8546  *   @ch_type : channel type
   8547  *
   8548  * RETURN     : int32_t type of status
   8549  *              NO_ERROR  -- success
   8550  *              none-zero failure code
   8551  *==========================================================================*/
   8552 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
   8553 {
   8554     int32_t rc = UNKNOWN_ERROR;
   8555     if (m_channels[ch_type] != NULL) {
   8556         rc = m_channels[ch_type]->start();
   8557     }
   8558     return rc;
   8559 }
   8560 
   8561 /*===========================================================================
   8562  * FUNCTION   : stopChannel
   8563  *
   8564  * DESCRIPTION: stop a channel by its type
   8565  *
   8566  * PARAMETERS :
   8567  *   @ch_type : channel type
   8568  *
   8569  * RETURN     : int32_t type of status
   8570  *              NO_ERROR  -- success
   8571  *              none-zero failure code
   8572  *==========================================================================*/
   8573 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
   8574 {
   8575     int32_t rc = UNKNOWN_ERROR;
   8576     if (m_channels[ch_type] != NULL) {
   8577         rc = m_channels[ch_type]->stop();
   8578     }
   8579 
   8580     return rc;
   8581 }
   8582 
   8583 /*===========================================================================
   8584  * FUNCTION   : preparePreview
   8585  *
   8586  * DESCRIPTION: add channels needed for preview
   8587  *
   8588  * PARAMETERS : none
   8589  *
   8590  * RETURN     : int32_t type of status
   8591  *              NO_ERROR  -- success
   8592  *              none-zero failure code
   8593  *==========================================================================*/
   8594 int32_t QCamera2HardwareInterface::preparePreview()
   8595 {
   8596     ATRACE_CALL();
   8597     int32_t rc = NO_ERROR;
   8598 
   8599     LOGI("E");
   8600     rc = mParameters.setStreamConfigure(false, false, false);
   8601     if (rc != NO_ERROR) {
   8602         LOGE("setStreamConfigure failed %d", rc);
   8603         return rc;
   8604     }
   8605 
   8606     if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
   8607         rc = addChannel(QCAMERA_CH_TYPE_ZSL);
   8608         if (rc != NO_ERROR) {
   8609             LOGE("failed!! rc = %d", rc);
   8610             return rc;
   8611         }
   8612 
   8613         if (mParameters.isUBWCEnabled()) {
   8614             cam_format_t fmt;
   8615             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
   8616             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   8617                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
   8618                 if (rc != NO_ERROR) {
   8619                     delChannel(QCAMERA_CH_TYPE_ZSL);
   8620                     LOGE("failed!! rc = %d", rc);
   8621                     return rc;
   8622                 }
   8623             }
   8624         }
   8625 
   8626         if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) {
   8627             addChannel(QCAMERA_CH_TYPE_RAW);
   8628         }
   8629     } else {
   8630         bool recordingHint = mParameters.getRecordingHintValue();
   8631         if(!isRdiMode() && recordingHint) {
   8632             //stop face detection,longshot,etc if turned ON in Camera mode
   8633 #ifndef VANILLA_HAL
   8634             int32_t arg; //dummy arg
   8635             if (isLongshotEnabled()) {
   8636                 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
   8637             }
   8638             if (mParameters.isFaceDetectionEnabled()
   8639                     && (!mParameters.fdModeInVideo())) {
   8640                 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
   8641             }
   8642             if (mParameters.isHistogramEnabled()) {
   8643                 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
   8644             }
   8645 #endif
   8646             //Don't create snapshot channel for liveshot, if low power mode is set.
   8647             //Use video stream instead.
   8648             if (!isLowPowerMode()) {
   8649                rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8650                if (rc != NO_ERROR) {
   8651                    return rc;
   8652                }
   8653             }
   8654 
   8655             rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
   8656             if (rc != NO_ERROR) {
   8657                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8658                 LOGE("failed!! rc = %d", rc);
   8659                 return rc;
   8660             }
   8661         }
   8662 
   8663         rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
   8664         if (!isRdiMode() && (rc != NO_ERROR)) {
   8665             if (recordingHint) {
   8666                 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8667                 delChannel(QCAMERA_CH_TYPE_VIDEO);
   8668             }
   8669         }
   8670 
   8671         if (mParameters.isUBWCEnabled() && !recordingHint) {
   8672             cam_format_t fmt;
   8673             mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
   8674             if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
   8675                 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
   8676                 if (rc != NO_ERROR) {
   8677                     delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8678                     if (!isRdiMode()) {
   8679                         delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8680                         delChannel(QCAMERA_CH_TYPE_VIDEO);
   8681                     }
   8682                     LOGE("failed!! rc = %d", rc);
   8683                     return rc;
   8684                 }
   8685             }
   8686         }
   8687 
   8688         if (NO_ERROR != rc) {
   8689             delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8690             LOGE("failed!! rc = %d", rc);
   8691         }
   8692     }
   8693 
   8694     LOGI("X rc = %d", rc);
   8695     return rc;
   8696 }
   8697 
   8698 /*===========================================================================
   8699  * FUNCTION   : unpreparePreview
   8700  *
   8701  * DESCRIPTION: delete channels for preview
   8702  *
   8703  * PARAMETERS : none
   8704  *
   8705  * RETURN     : none
   8706  *==========================================================================*/
   8707 void QCamera2HardwareInterface::unpreparePreview()
   8708 {
   8709     delChannel(QCAMERA_CH_TYPE_ZSL);
   8710     delChannel(QCAMERA_CH_TYPE_PREVIEW);
   8711     delChannel(QCAMERA_CH_TYPE_VIDEO);
   8712     delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
   8713     delChannel(QCAMERA_CH_TYPE_CALLBACK);
   8714     delChannel(QCAMERA_CH_TYPE_RAW);
   8715 }
   8716 
   8717 /*===========================================================================
   8718  * FUNCTION   : playShutter
   8719  *
   8720  * DESCRIPTION: send request to play shutter sound
   8721  *
   8722  * PARAMETERS : none
   8723  *
   8724  * RETURN     : none
   8725  *==========================================================================*/
   8726 void QCamera2HardwareInterface::playShutter(){
   8727      if (mNotifyCb == NULL ||
   8728          msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
   8729          LOGD("shutter msg not enabled or NULL cb");
   8730          return;
   8731      }
   8732      LOGH("CAMERA_MSG_SHUTTER ");
   8733      qcamera_callback_argm_t cbArg;
   8734      memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   8735      cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
   8736      cbArg.msg_type = CAMERA_MSG_SHUTTER;
   8737      cbArg.ext1 = 0;
   8738      cbArg.ext2 = false;
   8739      m_cbNotifier.notifyCallback(cbArg);
   8740 }
   8741 
   8742 /*===========================================================================
   8743  * FUNCTION   : getChannelByHandle
   8744  *
   8745  * DESCRIPTION: return a channel by its handle
   8746  *
   8747  * PARAMETERS :
   8748  *   @channelHandle : channel handle
   8749  *
   8750  * RETURN     : a channel obj if found, NULL if not found
   8751  *==========================================================================*/
   8752 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
   8753 {
   8754     for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   8755         if (m_channels[i] != NULL &&
   8756             (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
   8757             return m_channels[i];
   8758         }
   8759     }
   8760 
   8761     return NULL;
   8762 }
   8763 /*===========================================================================
   8764  * FUNCTION   : needPreviewFDCallback
   8765  *
   8766  * DESCRIPTION: decides if needPreviewFDCallback
   8767  *
   8768  * PARAMETERS :
   8769  *   @num_faces : number of faces
   8770  *
   8771  * RETURN     : bool type of status
   8772  *              true  -- success
   8773  *              fale -- failure code
   8774  *==========================================================================*/
   8775 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
   8776 {
   8777     if (num_faces == 0 && mNumPreviewFaces == 0) {
   8778         return false;
   8779     }
   8780 
   8781     return true;
   8782 }
   8783 
   8784 /*===========================================================================
   8785  * FUNCTION   : processFaceDetectionReuslt
   8786  *
   8787  * DESCRIPTION: process face detection reuslt
   8788  *
   8789  * PARAMETERS :
   8790  *   @faces_data : ptr to face processing result struct
   8791  *
   8792  * RETURN     : int32_t type of status
   8793  *              NO_ERROR  -- success
   8794  *              none-zero failure code
   8795  *==========================================================================*/
   8796 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
   8797 {
   8798     if (!mParameters.isFaceDetectionEnabled()) {
   8799         LOGH("FaceDetection not enabled, no ops here");
   8800         return NO_ERROR;
   8801     }
   8802 
   8803     qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
   8804     cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
   8805     if ((NULL == mDataCb) ||
   8806         (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
   8807         (!needPreviewFDCallback(detect_data->num_faces_detected))
   8808 #ifndef VANILLA_HAL
   8809         || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
   8810 #endif
   8811         ) {
   8812         LOGH("metadata msgtype not enabled, no ops here");
   8813         return NO_ERROR;
   8814     }
   8815 
   8816     if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
   8817         // Don't send callback to app if this is skipped by fd at backend
   8818         return NO_ERROR;
   8819     }
   8820 
   8821     cam_dimension_t display_dim;
   8822     mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
   8823     if (display_dim.width <= 0 || display_dim.height <= 0) {
   8824         LOGE("Invalid preview width or height (%d x %d)",
   8825                display_dim.width, display_dim.height);
   8826         return UNKNOWN_ERROR;
   8827     }
   8828 
   8829     // process face detection result
   8830     // need separate face detection in preview or snapshot type
   8831     size_t faceResultSize = 0;
   8832     size_t data_len = 0;
   8833     if(fd_type == QCAMERA_FD_PREVIEW){
   8834         //fd for preview frames
   8835         faceResultSize = sizeof(camera_frame_metadata_t);
   8836         faceResultSize += sizeof(camera_face_t) * MAX_ROI;
   8837     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
   8838 #ifndef VANILLA_HAL
   8839         // fd for snapshot frames
   8840         //check if face is detected in this frame
   8841         if(detect_data->num_faces_detected > 0){
   8842             data_len = sizeof(camera_frame_metadata_t) +
   8843                     sizeof(camera_face_t) * detect_data->num_faces_detected;
   8844         }else{
   8845             //no face
   8846             data_len = 0;
   8847         }
   8848 #endif
   8849         faceResultSize = 1 *sizeof(int)    //meta data type
   8850                        + 1 *sizeof(int)    // meta data len
   8851                        + data_len;         //data
   8852     }
   8853 
   8854     camera_memory_t *faceResultBuffer = mGetMemory(-1,
   8855                                                    faceResultSize,
   8856                                                    1,
   8857                                                    mCallbackCookie);
   8858     if ( NULL == faceResultBuffer ) {
   8859         LOGE("Not enough memory for face result data");
   8860         return NO_MEMORY;
   8861     }
   8862 
   8863     unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
   8864     memset(pFaceResult, 0, faceResultSize);
   8865     unsigned char *faceData = NULL;
   8866     if(fd_type == QCAMERA_FD_PREVIEW){
   8867         faceData = pFaceResult;
   8868         mNumPreviewFaces = detect_data->num_faces_detected;
   8869     }else if(fd_type == QCAMERA_FD_SNAPSHOT){
   8870 #ifndef VANILLA_HAL
   8871         //need fill meta type and meta data len first
   8872         int *data_header = (int* )pFaceResult;
   8873         data_header[0] = CAMERA_META_DATA_FD;
   8874         data_header[1] = (int)data_len;
   8875 
   8876         if(data_len <= 0){
   8877             //if face is not valid or do not have face, return
   8878             qcamera_callback_argm_t cbArg;
   8879             memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   8880             cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   8881             cbArg.msg_type = CAMERA_MSG_META_DATA;
   8882             cbArg.data = faceResultBuffer;
   8883             cbArg.user_data = faceResultBuffer;
   8884             cbArg.cookie = this;
   8885             cbArg.release_cb = releaseCameraMemory;
   8886             int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   8887             if (rc != NO_ERROR) {
   8888                 LOGE("fail sending notification");
   8889                 faceResultBuffer->release(faceResultBuffer);
   8890             }
   8891             return rc;
   8892         }
   8893 #endif
   8894         faceData = pFaceResult + 2 *sizeof(int); //skip two int length
   8895     }
   8896 
   8897     camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
   8898     camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
   8899 
   8900     roiData->number_of_faces = detect_data->num_faces_detected;
   8901     roiData->faces = faces;
   8902     if (roiData->number_of_faces > 0) {
   8903         for (int i = 0; i < roiData->number_of_faces; i++) {
   8904             faces[i].id = detect_data->faces[i].face_id;
   8905             faces[i].score = detect_data->faces[i].score;
   8906 
   8907             // left
   8908             faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
   8909                     detect_data->faces[i].face_boundary.left,
   8910                     display_dim.width, 2000, -1000);
   8911 
   8912             // top
   8913             faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
   8914                     detect_data->faces[i].face_boundary.top,
   8915                     display_dim.height, 2000, -1000);
   8916 
   8917             // right
   8918             faces[i].rect[2] = faces[i].rect[0] +
   8919                     MAP_TO_DRIVER_COORDINATE(
   8920                     detect_data->faces[i].face_boundary.width,
   8921                     display_dim.width, 2000, 0);
   8922 
   8923              // bottom
   8924             faces[i].rect[3] = faces[i].rect[1] +
   8925                     MAP_TO_DRIVER_COORDINATE(
   8926                     detect_data->faces[i].face_boundary.height,
   8927                     display_dim.height, 2000, 0);
   8928 
   8929             if (faces_data->landmark_valid) {
   8930                 // Center of left eye
   8931                 if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) {
   8932                     faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
   8933                             faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
   8934                             display_dim.width, 2000, -1000);
   8935                     faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
   8936                             faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
   8937                             display_dim.height, 2000, -1000);
   8938                 } else {
   8939                     faces[i].left_eye[0] = FACE_INVALID_POINT;
   8940                     faces[i].left_eye[1] = FACE_INVALID_POINT;
   8941                 }
   8942 
   8943                 // Center of right eye
   8944                 if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) {
   8945                     faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
   8946                             faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
   8947                             display_dim.width, 2000, -1000);
   8948                     faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
   8949                             faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
   8950                             display_dim.height, 2000, -1000);
   8951                 } else {
   8952                     faces[i].right_eye[0] = FACE_INVALID_POINT;
   8953                     faces[i].right_eye[1] = FACE_INVALID_POINT;
   8954                 }
   8955 
   8956                 // Center of mouth
   8957                 if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) {
   8958                     faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
   8959                             faces_data->landmark_data.face_landmarks[i].mouth_center.x,
   8960                             display_dim.width, 2000, -1000);
   8961                     faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
   8962                             faces_data->landmark_data.face_landmarks[i].mouth_center.y,
   8963                             display_dim.height, 2000, -1000);
   8964                 } else {
   8965                     faces[i].mouth[0] = FACE_INVALID_POINT;
   8966                     faces[i].mouth[1] = FACE_INVALID_POINT;
   8967                 }
   8968             } else {
   8969                 // return -2000 if invalid
   8970                 faces[i].left_eye[0] = FACE_INVALID_POINT;
   8971                 faces[i].left_eye[1] = FACE_INVALID_POINT;
   8972 
   8973                 faces[i].right_eye[0] = FACE_INVALID_POINT;
   8974                 faces[i].right_eye[1] = FACE_INVALID_POINT;
   8975 
   8976                 faces[i].mouth[0] = FACE_INVALID_POINT;
   8977                 faces[i].mouth[1] = FACE_INVALID_POINT;
   8978             }
   8979 
   8980 #ifndef VANILLA_HAL
   8981 #ifdef TARGET_TS_MAKEUP
   8982             mFaceRect.left = detect_data->faces[i].face_boundary.left;
   8983             mFaceRect.top = detect_data->faces[i].face_boundary.top;
   8984             mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
   8985             mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
   8986 #endif
   8987             if (faces_data->smile_valid) {
   8988                 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
   8989                 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
   8990             }
   8991             if (faces_data->blink_valid) {
   8992                 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
   8993                 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
   8994                 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
   8995             }
   8996             if (faces_data->recog_valid) {
   8997                 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
   8998             }
   8999             if (faces_data->gaze_valid) {
   9000                 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
   9001                 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
   9002                 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
   9003                 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
   9004                 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
   9005                 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
   9006             }
   9007 #endif
   9008 
   9009         }
   9010     }
   9011     else{
   9012 #ifdef TARGET_TS_MAKEUP
   9013         memset(&mFaceRect,-1,sizeof(mFaceRect));
   9014 #endif
   9015     }
   9016     qcamera_callback_argm_t cbArg;
   9017     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   9018     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   9019     if(fd_type == QCAMERA_FD_PREVIEW){
   9020         cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
   9021     }
   9022 #ifndef VANILLA_HAL
   9023     else if(fd_type == QCAMERA_FD_SNAPSHOT){
   9024         cbArg.msg_type = CAMERA_MSG_META_DATA;
   9025     }
   9026 #endif
   9027     cbArg.data = faceResultBuffer;
   9028     cbArg.metadata = roiData;
   9029     cbArg.user_data = faceResultBuffer;
   9030     cbArg.cookie = this;
   9031     cbArg.release_cb = releaseCameraMemory;
   9032     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   9033     if (rc != NO_ERROR) {
   9034         LOGE("fail sending notification");
   9035         faceResultBuffer->release(faceResultBuffer);
   9036     }
   9037 
   9038     return rc;
   9039 }
   9040 
   9041 /*===========================================================================
   9042  * FUNCTION   : releaseCameraMemory
   9043  *
   9044  * DESCRIPTION: releases camera memory objects
   9045  *
   9046  * PARAMETERS :
   9047  *   @data    : buffer to be released
   9048  *   @cookie  : context data
   9049  *   @cbStatus: callback status
   9050  *
   9051  * RETURN     : None
   9052  *==========================================================================*/
   9053 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
   9054                                                     void */*cookie*/,
   9055                                                     int32_t /*cbStatus*/)
   9056 {
   9057     camera_memory_t *mem = ( camera_memory_t * ) data;
   9058     if ( NULL != mem ) {
   9059         mem->release(mem);
   9060     }
   9061 }
   9062 
   9063 /*===========================================================================
   9064  * FUNCTION   : returnStreamBuffer
   9065  *
   9066  * DESCRIPTION: returns back a stream buffer
   9067  *
   9068  * PARAMETERS :
   9069  *   @data    : buffer to be released
   9070  *   @cookie  : context data
   9071  *   @cbStatus: callback status
   9072  *
   9073  * RETURN     : None
   9074  *==========================================================================*/
   9075 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
   9076                                                    void *cookie,
   9077                                                    int32_t /*cbStatus*/)
   9078 {
   9079     QCameraStream *stream = ( QCameraStream * ) cookie;
   9080     int idx = *((int *)data);
   9081     if ((NULL != stream) && (0 <= idx)) {
   9082         stream->bufDone((uint32_t)idx);
   9083     } else {
   9084         LOGE("Cannot return buffer %d %p", idx, cookie);
   9085     }
   9086 }
   9087 
   9088 /*===========================================================================
   9089  * FUNCTION   : processHistogramStats
   9090  *
   9091  * DESCRIPTION: process histogram stats
   9092  *
   9093  * PARAMETERS :
   9094  *   @hist_data : ptr to histogram stats struct
   9095  *
   9096  * RETURN     : int32_t type of status
   9097  *              NO_ERROR  -- success
   9098  *              none-zero failure code
   9099  *==========================================================================*/
   9100 int32_t QCamera2HardwareInterface::processHistogramStats(
   9101         __unused cam_hist_stats_t &stats_data)
   9102 {
   9103 #ifndef VANILLA_HAL
   9104     if (!mParameters.isHistogramEnabled()) {
   9105         LOGH("Histogram not enabled, no ops here");
   9106         return NO_ERROR;
   9107     }
   9108 
   9109     camera_memory_t *histBuffer = mGetMemory(-1,
   9110                                              sizeof(cam_histogram_data_t),
   9111                                              1,
   9112                                              mCallbackCookie);
   9113     if ( NULL == histBuffer ) {
   9114         LOGE("Not enough memory for histogram data");
   9115         return NO_MEMORY;
   9116     }
   9117 
   9118     cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
   9119     if (pHistData == NULL) {
   9120         LOGE("memory data ptr is NULL");
   9121         return UNKNOWN_ERROR;
   9122     }
   9123 
   9124     switch (stats_data.type) {
   9125     case CAM_HISTOGRAM_TYPE_BAYER:
   9126         switch (stats_data.bayer_stats.data_type) {
   9127             case CAM_STATS_CHANNEL_Y:
   9128             case CAM_STATS_CHANNEL_R:
   9129                 *pHistData = stats_data.bayer_stats.r_stats;
   9130                 break;
   9131             case CAM_STATS_CHANNEL_GR:
   9132                 *pHistData = stats_data.bayer_stats.gr_stats;
   9133                 break;
   9134             case CAM_STATS_CHANNEL_GB:
   9135             case CAM_STATS_CHANNEL_ALL:
   9136                 *pHistData = stats_data.bayer_stats.gb_stats;
   9137                 break;
   9138             case CAM_STATS_CHANNEL_B:
   9139                 *pHistData = stats_data.bayer_stats.b_stats;
   9140                 break;
   9141             default:
   9142                 *pHistData = stats_data.bayer_stats.r_stats;
   9143                 break;
   9144         }
   9145         break;
   9146     case CAM_HISTOGRAM_TYPE_YUV:
   9147         *pHistData = stats_data.yuv_stats;
   9148         break;
   9149     }
   9150 
   9151     qcamera_callback_argm_t cbArg;
   9152     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
   9153     cbArg.cb_type = QCAMERA_DATA_CALLBACK;
   9154     cbArg.msg_type = CAMERA_MSG_STATS_DATA;
   9155     cbArg.data = histBuffer;
   9156     cbArg.user_data = histBuffer;
   9157     cbArg.cookie = this;
   9158     cbArg.release_cb = releaseCameraMemory;
   9159     int32_t rc = m_cbNotifier.notifyCallback(cbArg);
   9160     if (rc != NO_ERROR) {
   9161         LOGE("fail sending notification");
   9162         histBuffer->release(histBuffer);
   9163     }
   9164 #endif
   9165     return NO_ERROR;
   9166 }
   9167 
   9168 /*===========================================================================
   9169  * FUNCTION   : calcThermalLevel
   9170  *
   9171  * DESCRIPTION: Calculates the target fps range depending on
   9172  *              the thermal level.
   9173  *              Note that this function can be called from QCameraParametersIntf
   9174  *              while mutex is held. So it should not call back into
   9175  *              QCameraParametersIntf causing deadlock.
   9176  *
   9177  * PARAMETERS :
   9178  *   @level      : received thermal level
   9179  *   @minFPS     : minimum configured fps range
   9180  *   @maxFPS     : maximum configured fps range
   9181  *   @minVideoFps: minimum configured fps range
   9182  *   @maxVideoFps: maximum configured fps range
   9183  *   @adjustedRange : target fps range
   9184  *   @skipPattern : target skip pattern
   9185  *
   9186  * RETURN     : int32_t type of status
   9187  *              NO_ERROR  -- success
   9188  *              none-zero failure code
   9189  *==========================================================================*/
   9190 int QCamera2HardwareInterface::calcThermalLevel(
   9191             qcamera_thermal_level_enum_t level,
   9192             const int minFPSi,
   9193             const int maxFPSi,
   9194             const float &minVideoFps,
   9195             const float &maxVideoFps,
   9196             cam_fps_range_t &adjustedRange,
   9197             enum msm_vfe_frame_skip_pattern &skipPattern)
   9198 {
   9199     const float minFPS = (float)minFPSi;
   9200     const float maxFPS = (float)maxFPSi;
   9201 
   9202     LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
   9203               "video minfps %f, video maxfpS %f",
   9204              level, minFPS, maxFPS, minVideoFps, maxVideoFps);
   9205 
   9206     switch(level) {
   9207     case QCAMERA_THERMAL_NO_ADJUSTMENT:
   9208         {
   9209             adjustedRange.min_fps = minFPS / 1000.0f;
   9210             adjustedRange.max_fps = maxFPS / 1000.0f;
   9211             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   9212             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   9213             skipPattern = NO_SKIP;
   9214         }
   9215         break;
   9216     case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
   9217         {
   9218             adjustedRange.min_fps = minFPS / 1000.0f;
   9219             adjustedRange.max_fps = maxFPS / 1000.0f;
   9220             adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
   9221             adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
   9222             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   9223             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   9224             adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
   9225             adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
   9226             if ( adjustedRange.min_fps < 1 ) {
   9227                 adjustedRange.min_fps = 1;
   9228             }
   9229             if ( adjustedRange.max_fps < 1 ) {
   9230                 adjustedRange.max_fps = 1;
   9231             }
   9232             if ( adjustedRange.video_min_fps < 1 ) {
   9233                 adjustedRange.video_min_fps = 1;
   9234             }
   9235             if ( adjustedRange.video_max_fps < 1 ) {
   9236                 adjustedRange.video_max_fps = 1;
   9237             }
   9238             skipPattern = EVERY_2FRAME;
   9239         }
   9240         break;
   9241     case QCAMERA_THERMAL_BIG_ADJUSTMENT:
   9242         {
   9243             adjustedRange.min_fps = minFPS / 1000.0f;
   9244             adjustedRange.max_fps = maxFPS / 1000.0f;
   9245             adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
   9246             adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
   9247             adjustedRange.video_min_fps = minVideoFps / 1000.0f;
   9248             adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
   9249             adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
   9250             adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
   9251             if ( adjustedRange.min_fps < 1 ) {
   9252                 adjustedRange.min_fps = 1;
   9253             }
   9254             if ( adjustedRange.max_fps < 1 ) {
   9255                 adjustedRange.max_fps = 1;
   9256             }
   9257             if ( adjustedRange.video_min_fps < 1 ) {
   9258                 adjustedRange.video_min_fps = 1;
   9259             }
   9260             if ( adjustedRange.video_max_fps < 1 ) {
   9261                 adjustedRange.video_max_fps = 1;
   9262             }
   9263             skipPattern = EVERY_4FRAME;
   9264         }
   9265         break;
   9266     case QCAMERA_THERMAL_MAX_ADJUSTMENT:
   9267         {
   9268             // Stop Preview?
   9269             // Set lowest min FPS for now
   9270             adjustedRange.min_fps = minFPS/1000.0f;
   9271             adjustedRange.max_fps = minFPS/1000.0f;
   9272             cam_capability_t *capability = gCamCapability[mCameraId];
   9273             for (size_t i = 0;
   9274                      i < capability->fps_ranges_tbl_cnt;
   9275                      i++) {
   9276                 if (capability->fps_ranges_tbl[i].min_fps <
   9277                         adjustedRange.min_fps) {
   9278                     adjustedRange.min_fps =
   9279                             capability->fps_ranges_tbl[i].min_fps;
   9280                     adjustedRange.max_fps = adjustedRange.min_fps;
   9281                 }
   9282             }
   9283             skipPattern = MAX_SKIP;
   9284             adjustedRange.video_min_fps = adjustedRange.min_fps;
   9285             adjustedRange.video_max_fps = adjustedRange.max_fps;
   9286         }
   9287         break;
   9288     case QCAMERA_THERMAL_SHUTDOWN:
   9289         {
   9290             // send error notify
   9291             LOGE("Received shutdown thermal level. Closing camera");
   9292             sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
   9293         }
   9294         break;
   9295     default:
   9296         {
   9297             LOGW("Invalid thermal level %d", level);
   9298             return BAD_VALUE;
   9299         }
   9300         break;
   9301     }
   9302 
   9303     return NO_ERROR;
   9304 }
   9305 
   9306 /*===========================================================================
   9307  * FUNCTION   : recalcFPSRange
   9308  *
   9309  * DESCRIPTION: adjust the configured fps range regarding
   9310  *              the last thermal level.
   9311  *
   9312  * PARAMETERS :
   9313  *   @minFPS      : minimum configured fps range
   9314  *   @maxFPS      : maximum configured fps range
   9315  *   @minVideoFPS : minimum configured video fps
   9316  *   @maxVideoFPS : maximum configured video fps
   9317  *   @adjustedRange : target fps range
   9318  *
   9319  * RETURN     : int32_t type of status
   9320  *              NO_ERROR  -- success
   9321  *              none-zero failure code
   9322  *==========================================================================*/
   9323 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
   9324         const float &minVideoFPS, const float &maxVideoFPS,
   9325         cam_fps_range_t &adjustedRange)
   9326 {
   9327     enum msm_vfe_frame_skip_pattern skipPattern;
   9328     calcThermalLevel(mThermalLevel,
   9329                      minFPS,
   9330                      maxFPS,
   9331                      minVideoFPS,
   9332                      maxVideoFPS,
   9333                      adjustedRange,
   9334                      skipPattern);
   9335     return NO_ERROR;
   9336 }
   9337 
   9338 /*===========================================================================
   9339  * FUNCTION   : updateThermalLevel
   9340  *
   9341  * DESCRIPTION: update thermal level depending on thermal events
   9342  *
   9343  * PARAMETERS :
   9344  *   @level   : thermal level
   9345  *
   9346  * RETURN     : int32_t type of status
   9347  *              NO_ERROR  -- success
   9348  *              none-zero failure code
   9349  *==========================================================================*/
   9350 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
   9351 {
   9352     int ret = NO_ERROR;
   9353     cam_fps_range_t adjustedRange;
   9354     int minFPS, maxFPS;
   9355     float minVideoFPS, maxVideoFPS;
   9356     enum msm_vfe_frame_skip_pattern skipPattern;
   9357     qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
   9358 
   9359 
   9360     if (!mCameraOpened) {
   9361         LOGH("Camera is not opened, no need to update camera parameters");
   9362         return NO_ERROR;
   9363     }
   9364     if (mParameters.getRecordingHintValue()) {
   9365         LOGH("Thermal mitigation isn't enabled in camcorder mode");
   9366         return NO_ERROR;
   9367     }
   9368 
   9369     mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
   9370     qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
   9371     if (mParameters.isHfrMode()) {
   9372         cam_fps_range_t hfrFpsRange;
   9373         mParameters.getHfrFps(hfrFpsRange);
   9374         minVideoFPS = hfrFpsRange.video_min_fps;
   9375         maxVideoFPS = hfrFpsRange.video_max_fps;
   9376     } else {
   9377         minVideoFPS = minFPS;
   9378         maxVideoFPS = maxFPS;
   9379     }
   9380 
   9381     calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
   9382             adjustedRange, skipPattern);
   9383     mThermalLevel = level;
   9384 
   9385     if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
   9386         ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
   9387     else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
   9388         ret = mParameters.setFrameSkip(skipPattern);
   9389     else
   9390         LOGW("Incorrect thermal mode %d", thermalMode);
   9391 
   9392     return ret;
   9393 
   9394 }
   9395 
   9396 /*===========================================================================
   9397  * FUNCTION   : updateParameters
   9398  *
   9399  * DESCRIPTION: update parameters
   9400  *
   9401  * PARAMETERS :
   9402  *   @parms       : input parameters string
   9403  *   @needRestart : output, flag to indicate if preview restart is needed
   9404  *
   9405  * RETURN     : int32_t type of status
   9406  *              NO_ERROR  -- success
   9407  *              none-zero failure code
   9408  *==========================================================================*/
   9409 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
   9410 {
   9411     int rc = NO_ERROR;
   9412 
   9413     String8 str = String8(parms);
   9414     rc =  mParameters.updateParameters(str, needRestart);
   9415     setNeedRestart(needRestart);
   9416 
   9417     // update stream based parameter settings
   9418     for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
   9419         if (m_channels[i] != NULL) {
   9420             m_channels[i]->UpdateStreamBasedParameters(mParameters);
   9421         }
   9422     }
   9423 
   9424     return rc;
   9425 }
   9426 
   9427 /*===========================================================================
   9428  * FUNCTION   : commitParameterChanges
   9429  *
   9430  * DESCRIPTION: commit parameter changes to the backend to take effect
   9431  *
   9432  * PARAMETERS : none
   9433  *
   9434  * RETURN     : int32_t type of status
   9435  *              NO_ERROR  -- success
   9436  *              none-zero failure code
   9437  * NOTE       : This function must be called after updateParameters.
   9438  *              Otherwise, no change will be passed to backend to take effect.
   9439  *==========================================================================*/
   9440 int QCamera2HardwareInterface::commitParameterChanges()
   9441 {
   9442     int rc = NO_ERROR;
   9443     rc = mParameters.commitParameters();
   9444     if (rc == NO_ERROR) {
   9445         // update number of snapshot based on committed parameters setting
   9446         rc = mParameters.setNumOfSnapshot();
   9447     }
   9448     return rc;
   9449 }
   9450 
   9451 /*===========================================================================
   9452  * FUNCTION   : needDebugFps
   9453  *
   9454  * DESCRIPTION: if fps log info need to be printed out
   9455  *
   9456  * PARAMETERS : none
   9457  *
   9458  * RETURN     : true: need print out fps log
   9459  *              false: no need to print out fps log
   9460  *==========================================================================*/
   9461 bool QCamera2HardwareInterface::needDebugFps()
   9462 {
   9463     bool needFps = false;
   9464     needFps = mParameters.isFpsDebugEnabled();
   9465     return needFps;
   9466 }
   9467 
   9468 /*===========================================================================
   9469  * FUNCTION   : isCACEnabled
   9470  *
   9471  * DESCRIPTION: if CAC is enabled
   9472  *
   9473  * PARAMETERS : none
   9474  *
   9475  * RETURN     : true: needed
   9476  *              false: no need
   9477  *==========================================================================*/
   9478 bool QCamera2HardwareInterface::isCACEnabled()
   9479 {
   9480     char prop[PROPERTY_VALUE_MAX];
   9481     memset(prop, 0, sizeof(prop));
   9482     property_get("persist.camera.feature.cac", prop, "0");
   9483     int enableCAC = atoi(prop);
   9484     return enableCAC == 1;
   9485 }
   9486 
   9487 /*===========================================================================
   9488  * FUNCTION   : is4k2kResolution
   9489  *
   9490  * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
   9491  *
   9492  * PARAMETERS : none
   9493  *
   9494  * RETURN     : true: needed
   9495  *              false: no need
   9496  *==========================================================================*/
   9497 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
   9498 {
   9499    bool enabled = false;
   9500    if ((resolution->width == 4096 && resolution->height == 2160) ||
   9501        (resolution->width == 3840 && resolution->height == 2160) ) {
   9502       enabled = true;
   9503    }
   9504    return enabled;
   9505 }
   9506 
   9507 /*===========================================================================
   9508  * FUNCTION   : isPreviewRestartEnabled
   9509  *
   9510  * DESCRIPTION: Check whether preview should be restarted automatically
   9511  *              during image capture.
   9512  *
   9513  * PARAMETERS : none
   9514  *
   9515  * RETURN     : true: needed
   9516  *              false: no need
   9517  *==========================================================================*/
   9518 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
   9519 {
   9520     char prop[PROPERTY_VALUE_MAX];
   9521     memset(prop, 0, sizeof(prop));
   9522     property_get("persist.camera.feature.restart", prop, "0");
   9523     int earlyRestart = atoi(prop);
   9524     return earlyRestart == 1;
   9525 }
   9526 
   9527 /*===========================================================================
   9528  * FUNCTION   : needReprocess
   9529  *
   9530  * DESCRIPTION: if reprocess is needed
   9531  *
   9532  * PARAMETERS : none
   9533  *
   9534  * RETURN     : true: needed
   9535  *              false: no need
   9536  *==========================================================================*/
   9537 bool QCamera2HardwareInterface::needReprocess()
   9538 {
   9539     bool needReprocess = false;
   9540 
   9541     if (!mParameters.isJpegPictureFormat() &&
   9542         !mParameters.isNV21PictureFormat()) {
   9543         // RAW image, no need to reprocess
   9544         return false;
   9545     }
   9546 
   9547     //Disable reprocess for 4K liveshot case but enable if lowpower mode
   9548     if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
   9549             && !isLowPowerMode()) {
   9550         return false;
   9551     }
   9552 
   9553     // pp feature config
   9554     cam_pp_feature_config_t pp_config;
   9555     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
   9556 
   9557     //Decide whether to do reprocess or not based on
   9558     //ppconfig obtained in the first pass.
   9559     getPPConfig(pp_config);
   9560 
   9561     if (pp_config.feature_mask > 0) {
   9562         needReprocess = true;
   9563     }
   9564 
   9565     LOGH("needReprocess %s", needReprocess ? "true" : "false");
   9566     return needReprocess;
   9567 }
   9568 
   9569 
   9570 /*===========================================================================
   9571  * FUNCTION   : needRotationReprocess
   9572  *
   9573  * DESCRIPTION: if rotation needs to be done by reprocess in pp
   9574  *
   9575  * PARAMETERS : none
   9576  *
   9577  * RETURN     : true: needed
   9578  *              false: no need
   9579  *==========================================================================*/
   9580 bool QCamera2HardwareInterface::needRotationReprocess()
   9581 {
   9582     if (!mParameters.isJpegPictureFormat() &&
   9583         !mParameters.isNV21PictureFormat()) {
   9584         // RAW image, no need to reprocess
   9585         return false;
   9586     }
   9587 
   9588     //Disable reprocess for 4K liveshot case
   9589     if (mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
   9590             && !isLowPowerMode()) {
   9591         //Disable reprocess for 4K liveshot case
   9592         return false;
   9593     }
   9594 
   9595     if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
   9596             CAM_QCOM_FEATURE_ROTATION) > 0 &&
   9597             (mParameters.getJpegRotation() > 0)) {
   9598         // current rotation is not zero, and pp has the capability to process rotation
   9599         LOGH("need to do reprocess for rotation=%d",
   9600                  mParameters.getJpegRotation());
   9601         return true;
   9602     }
   9603 
   9604     return false;
   9605 }
   9606 
   9607 /*===========================================================================
   9608  * FUNCTION   : getThumbnailSize
   9609  *
   9610  * DESCRIPTION: get user set thumbnail size
   9611  *
   9612  * PARAMETERS :
   9613  *   @dim     : output of thumbnail dimension
   9614  *
   9615  * RETURN     : none
   9616  *==========================================================================*/
   9617 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
   9618 {
   9619     mParameters.getThumbnailSize(&dim.width, &dim.height);
   9620 }
   9621 
   9622 /*===========================================================================
   9623  * FUNCTION   : getJpegQuality
   9624  *
   9625  * DESCRIPTION: get user set jpeg quality
   9626  *
   9627  * PARAMETERS : none
   9628  *
   9629  * RETURN     : jpeg quality setting
   9630  *==========================================================================*/
   9631 uint32_t QCamera2HardwareInterface::getJpegQuality()
   9632 {
   9633     uint32_t quality = 0;
   9634     quality =  mParameters.getJpegQuality();
   9635     return quality;
   9636 }
   9637 
   9638 /*===========================================================================
   9639  * FUNCTION   : getExifData
   9640  *
   9641  * DESCRIPTION: get exif data to be passed into jpeg encoding
   9642  *
   9643  * PARAMETERS : none
   9644  *
   9645  * RETURN     : exif data from user setting and GPS
   9646  *==========================================================================*/
   9647 QCameraExif *QCamera2HardwareInterface::getExifData()
   9648 {
   9649     QCameraExif *exif = new QCameraExif();
   9650     if (exif == NULL) {
   9651         LOGE("No memory for QCameraExif");
   9652         return NULL;
   9653     }
   9654 
   9655     int32_t rc = NO_ERROR;
   9656 
   9657     // add exif entries
   9658     String8 dateTime, subSecTime;
   9659     rc = mParameters.getExifDateTime(dateTime, subSecTime);
   9660     if(rc == NO_ERROR) {
   9661         exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
   9662                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   9663         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
   9664                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   9665         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
   9666                 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
   9667         exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
   9668                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   9669         exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
   9670                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   9671         exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
   9672                 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
   9673     } else {
   9674         LOGW("getExifDateTime failed");
   9675     }
   9676 
   9677     rat_t focalLength;
   9678     rc = mParameters.getExifFocalLength(&focalLength);
   9679     if (rc == NO_ERROR) {
   9680         exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
   9681                        EXIF_RATIONAL,
   9682                        1,
   9683                        (void *)&(focalLength));
   9684     } else {
   9685         LOGW("getExifFocalLength failed");
   9686     }
   9687 
   9688     uint16_t isoSpeed = mParameters.getExifIsoSpeed();
   9689     if (getSensorType() != CAM_SENSOR_YUV) {
   9690         exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
   9691                        EXIF_SHORT,
   9692                        1,
   9693                        (void *)&(isoSpeed));
   9694     }
   9695 
   9696     char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
   9697     uint32_t count = 0;
   9698 
   9699     /*gps data might not be available */
   9700     rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
   9701     if(rc == NO_ERROR) {
   9702         exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
   9703                        EXIF_ASCII,
   9704                        count,
   9705                        (void *)gpsProcessingMethod);
   9706     } else {
   9707         LOGW("getExifGpsProcessingMethod failed");
   9708     }
   9709 
   9710     rat_t latitude[3];
   9711     char latRef[2];
   9712     rc = mParameters.getExifLatitude(latitude, latRef);
   9713     if(rc == NO_ERROR) {
   9714         exif->addEntry(EXIFTAGID_GPS_LATITUDE,
   9715                        EXIF_RATIONAL,
   9716                        3,
   9717                        (void *)latitude);
   9718         exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
   9719                        EXIF_ASCII,
   9720                        2,
   9721                        (void *)latRef);
   9722     } else {
   9723         LOGW("getExifLatitude failed");
   9724     }
   9725 
   9726     rat_t longitude[3];
   9727     char lonRef[2];
   9728     rc = mParameters.getExifLongitude(longitude, lonRef);
   9729     if(rc == NO_ERROR) {
   9730         exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
   9731                        EXIF_RATIONAL,
   9732                        3,
   9733                        (void *)longitude);
   9734 
   9735         exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
   9736                        EXIF_ASCII,
   9737                        2,
   9738                        (void *)lonRef);
   9739     } else {
   9740         LOGW("getExifLongitude failed");
   9741     }
   9742 
   9743     rat_t altitude;
   9744     char altRef;
   9745     rc = mParameters.getExifAltitude(&altitude, &altRef);
   9746     if(rc == NO_ERROR) {
   9747         exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
   9748                        EXIF_RATIONAL,
   9749                        1,
   9750                        (void *)&(altitude));
   9751 
   9752         exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
   9753                        EXIF_BYTE,
   9754                        1,
   9755                        (void *)&altRef);
   9756     } else {
   9757         LOGW("getExifAltitude failed");
   9758     }
   9759 
   9760     char gpsDateStamp[20];
   9761     rat_t gpsTimeStamp[3];
   9762     rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
   9763     if(rc == NO_ERROR) {
   9764         exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
   9765                        EXIF_ASCII,
   9766                        (uint32_t)(strlen(gpsDateStamp) + 1),
   9767                        (void *)gpsDateStamp);
   9768 
   9769         exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
   9770                        EXIF_RATIONAL,
   9771                        3,
   9772                        (void *)gpsTimeStamp);
   9773     } else {
   9774         LOGW("getExifGpsDataTimeStamp failed");
   9775     }
   9776 
   9777 #ifdef ENABLE_MODEL_INFO_EXIF
   9778 
   9779     char value[PROPERTY_VALUE_MAX];
   9780     if (property_get("persist.sys.exif.make", value, "") > 0 ||
   9781             property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
   9782         exif->addEntry(EXIFTAGID_MAKE,
   9783                 EXIF_ASCII, strlen(value) + 1, (void *)value);
   9784     } else {
   9785         LOGW("getExifMaker failed");
   9786     }
   9787 
   9788     if (property_get("persist.sys.exif.model", value, "") > 0 ||
   9789             property_get("ro.product.model", value, "QCAM-AA") > 0) {
   9790         exif->addEntry(EXIFTAGID_MODEL,
   9791                 EXIF_ASCII, strlen(value) + 1, (void *)value);
   9792     } else {
   9793         LOGW("getExifModel failed");
   9794     }
   9795 
   9796     if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
   9797         exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
   9798                 (uint32_t)(strlen(value) + 1), (void *)value);
   9799     } else {
   9800         LOGW("getExifSoftware failed");
   9801     }
   9802 
   9803 #endif
   9804 
   9805     if (mParameters.useJpegExifRotation()) {
   9806         int16_t orientation;
   9807         switch (mParameters.getJpegExifRotation()) {
   9808         case 0:
   9809             orientation = 1;
   9810             break;
   9811         case 90:
   9812             orientation = 6;
   9813             break;
   9814         case 180:
   9815             orientation = 3;
   9816             break;
   9817         case 270:
   9818             orientation = 8;
   9819             break;
   9820         default:
   9821             orientation = 1;
   9822             break;
   9823         }
   9824         exif->addEntry(EXIFTAGID_ORIENTATION,
   9825                 EXIF_SHORT,
   9826                 1,
   9827                 (void *)&orientation);
   9828         exif->addEntry(EXIFTAGID_TN_ORIENTATION,
   9829                 EXIF_SHORT,
   9830                 1,
   9831                 (void *)&orientation);
   9832     }
   9833 
   9834     return exif;
   9835 }
   9836 
   9837 /*===========================================================================
   9838  * FUNCTION   : setHistogram
   9839  *
   9840  * DESCRIPTION: set if histogram should be enabled
   9841  *
   9842  * PARAMETERS :
   9843  *   @histogram_en : bool flag if histogram should be enabled
   9844  *
   9845  * RETURN     : int32_t type of status
   9846  *              NO_ERROR  -- success
   9847  *              none-zero failure code
   9848  *==========================================================================*/
   9849 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
   9850 {
   9851     return mParameters.setHistogram(histogram_en);
   9852 }
   9853 
   9854 /*===========================================================================
   9855  * FUNCTION   : setFaceDetection
   9856  *
   9857  * DESCRIPTION: set if face detection should be enabled
   9858  *
   9859  * PARAMETERS :
   9860  *   @enabled : bool flag if face detection should be enabled
   9861  *
   9862  * RETURN     : int32_t type of status
   9863  *              NO_ERROR  -- success
   9864  *              none-zero failure code
   9865  *==========================================================================*/
   9866 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
   9867 {
   9868     return mParameters.setFaceDetection(enabled, true);
   9869 }
   9870 
   9871 /*===========================================================================
   9872  * FUNCTION   : isCaptureShutterEnabled
   9873  *
   9874  * DESCRIPTION: Check whether shutter should be triggered immediately after
   9875  *              capture
   9876  *
   9877  * PARAMETERS :
   9878  *
   9879  * RETURN     : true - regular capture
   9880  *              false - other type of capture
   9881  *==========================================================================*/
   9882 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
   9883 {
   9884     char prop[PROPERTY_VALUE_MAX];
   9885     memset(prop, 0, sizeof(prop));
   9886     property_get("persist.camera.feature.shutter", prop, "0");
   9887     int enableShutter = atoi(prop);
   9888     return enableShutter == 1;
   9889 }
   9890 
   9891 /*===========================================================================
   9892  * FUNCTION   : needProcessPreviewFrame
   9893  *
   9894  * DESCRIPTION: returns whether preview frame need to be displayed
   9895  *
   9896  * PARAMETERS :
   9897  *   @frameID : frameID of frame to be processed
   9898  *
   9899  * RETURN     : int32_t type of status
   9900  *              NO_ERROR  -- success
   9901  *              none-zero failure code
   9902  *==========================================================================*/
   9903 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
   9904 {
   9905     return (((m_stateMachine.isPreviewRunning()) &&
   9906             (!isDisplayFrameToSkip(frameID)) &&
   9907             (!mParameters.isInstantAECEnabled())) ||
   9908             (isPreviewRestartEnabled()));
   9909 }
   9910 
   9911 /*===========================================================================
   9912  * FUNCTION   : needSendPreviewCallback
   9913  *
   9914  * DESCRIPTION: returns whether preview frame need to callback to APP
   9915  *
   9916  * PARAMETERS :
   9917  *
   9918  * RETURN     : true - need preview frame callbck
   9919  *              false - not send preview frame callback
   9920  *==========================================================================*/
   9921 bool QCamera2HardwareInterface::needSendPreviewCallback()
   9922 {
   9923     return m_stateMachine.isPreviewRunning()
   9924             && (mDataCb != NULL)
   9925             && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
   9926             && m_stateMachine.isPreviewCallbackNeeded();
   9927 };
   9928 
   9929 /*===========================================================================
   9930  * FUNCTION   : setDisplaySkip
   9931  *
   9932  * DESCRIPTION: set range of frames to skip for preview
   9933  *
   9934  * PARAMETERS :
   9935  *   @enabled : TRUE to start skipping frame to display
   9936                 FALSE to stop skipping frame to display
   9937  *   @skipCnt : Number of frame to skip. 0 by default
   9938  *
   9939  * RETURN     : None
   9940  *==========================================================================*/
   9941 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
   9942 {
   9943     pthread_mutex_lock(&mGrallocLock);
   9944     if (enabled) {
   9945         setDisplayFrameSkip();
   9946         setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
   9947     } else {
   9948         setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
   9949     }
   9950     pthread_mutex_unlock(&mGrallocLock);
   9951 }
   9952 
   9953 /*===========================================================================
   9954  * FUNCTION   : setDisplayFrameSkip
   9955  *
   9956  * DESCRIPTION: set range of frames to skip for preview
   9957  *
   9958  * PARAMETERS :
   9959  *   @start   : frameId to start skip
   9960  *   @end     : frameId to stop skip
   9961  *
   9962  * RETURN     : None
   9963  *==========================================================================*/
   9964 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
   9965         uint32_t end)
   9966 {
   9967     if (start == 0) {
   9968         mFrameSkipStart = 0;
   9969         mFrameSkipEnd = 0;
   9970         return;
   9971     }
   9972     if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
   9973         mFrameSkipStart = start;
   9974     }
   9975     if ((end == 0) || (end > mFrameSkipEnd)) {
   9976         mFrameSkipEnd = end;
   9977     }
   9978 }
   9979 
   9980 /*===========================================================================
   9981  * FUNCTION   : isDisplayFrameToSkip
   9982  *
   9983  * DESCRIPTION: function to determin if input frame falls under skip range
   9984  *
   9985  * PARAMETERS :
   9986  *   @frameId : frameId to verify
   9987  *
   9988  * RETURN     : true : need to skip
   9989  *              false: no need to skip
   9990  *==========================================================================*/
   9991 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
   9992 {
   9993     return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
   9994             (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
   9995 }
   9996 
   9997 /*===========================================================================
   9998  * FUNCTION   : prepareHardwareForSnapshot
   9999  *
   10000  * DESCRIPTION: prepare hardware for snapshot, such as LED
   10001  *
   10002  * PARAMETERS :
   10003  *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
   10004  *
   10005  * RETURN     : int32_t type of status
   10006  *              NO_ERROR  -- success
   10007  *              none-zero failure code
   10008  *==========================================================================*/
   10009 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
   10010 {
   10011     ATRACE_CALL();
   10012     LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
   10013     return mCameraHandle->ops->prepare_snapshot(mCameraHandle->camera_handle,
   10014                                                 afNeeded);
   10015 }
   10016 
   10017 /*===========================================================================
   10018  * FUNCTION   : needFDMetadata
   10019  *
   10020  * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
   10021  *
   10022  * PARAMETERS :
   10023  *   @channel_type: channel type
   10024  *
   10025   * RETURN     : true: needed
   10026  *              false: no need
   10027  *==========================================================================*/
   10028 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
   10029 {
   10030     //Note: Currently we only process ZSL channel
   10031     bool value = false;
   10032     if(channel_type == QCAMERA_CH_TYPE_ZSL){
   10033         //check if FD requirement is enabled
   10034         if(mParameters.isSnapshotFDNeeded() &&
   10035            mParameters.isFaceDetectionEnabled()){
   10036             value = true;
   10037             LOGH("Face Detection metadata is required in ZSL mode.");
   10038         }
   10039     }
   10040 
   10041     return value;
   10042 }
   10043 
   10044 /*===========================================================================
   10045  * FUNCTION   : deferredWorkRoutine
   10046  *
   10047  * DESCRIPTION: data process routine that executes deferred tasks
   10048  *
   10049  * PARAMETERS :
   10050  *   @data    : user data ptr (QCamera2HardwareInterface)
   10051  *
   10052  * RETURN     : None
   10053  *==========================================================================*/
   10054 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
   10055 {
   10056     int running = 1;
   10057     int ret;
   10058     uint8_t is_active = FALSE;
   10059     int32_t job_status = 0;
   10060 
   10061     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
   10062     QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
   10063     cmdThread->setName("CAM_defrdWrk");
   10064 
   10065     do {
   10066         do {
   10067             ret = cam_sem_wait(&cmdThread->cmd_sem);
   10068             if (ret != 0 && errno != EINVAL) {
   10069                 LOGE("cam_sem_wait error (%s)",
   10070                          strerror(errno));
   10071                 return NULL;
   10072             }
   10073         } while (ret != 0);
   10074 
   10075         // we got notified about new cmd avail in cmd queue
   10076         camera_cmd_type_t cmd = cmdThread->getCmd();
   10077         LOGD("cmd: %d", cmd);
   10078         switch (cmd) {
   10079         case CAMERA_CMD_TYPE_START_DATA_PROC:
   10080             LOGH("start data proc");
   10081             is_active = TRUE;
   10082             break;
   10083         case CAMERA_CMD_TYPE_STOP_DATA_PROC:
   10084             LOGH("stop data proc");
   10085             is_active = FALSE;
   10086             // signal cmd is completed
   10087             cam_sem_post(&cmdThread->sync_sem);
   10088             break;
   10089         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
   10090             {
   10091                 DefWork *dw =
   10092                     reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
   10093 
   10094                 if ( NULL == dw ) {
   10095                     LOGE("Invalid deferred work");
   10096                     break;
   10097                 }
   10098 
   10099                 switch( dw->cmd ) {
   10100                 case CMD_DEF_ALLOCATE_BUFF:
   10101                     {
   10102                         QCameraChannel * pChannel = dw->args.allocArgs.ch;
   10103 
   10104                         if ( NULL == pChannel ) {
   10105                             LOGE("Invalid deferred work channel");
   10106                             job_status = BAD_VALUE;
   10107                             break;
   10108                         }
   10109 
   10110                         cam_stream_type_t streamType = dw->args.allocArgs.type;
   10111                         LOGH("Deferred buffer allocation started for stream type: %d",
   10112                                  streamType);
   10113 
   10114                         uint32_t iNumOfStreams = pChannel->getNumOfStreams();
   10115                         QCameraStream *pStream = NULL;
   10116                         for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
   10117                             pStream = pChannel->getStreamByIndex(i);
   10118 
   10119                             if ( NULL == pStream ) {
   10120                                 job_status = BAD_VALUE;
   10121                                 break;
   10122                             }
   10123 
   10124                             if ( pStream->isTypeOf(streamType)) {
   10125                                 if ( pStream->allocateBuffers() ) {
   10126                                     LOGE("Error allocating buffers !!!");
   10127                                     job_status =  NO_MEMORY;
   10128                                     pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10129                                             CAMERA_ERROR_UNKNOWN, 0);
   10130                                 }
   10131                                 break;
   10132                             }
   10133                         }
   10134                     }
   10135                     break;
   10136                 case CMD_DEF_PPROC_START:
   10137                     {
   10138                         int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
   10139                         if (ret != NO_ERROR) {
   10140                             job_status = ret;
   10141                             LOGE("PPROC Start failed");
   10142                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10143                                     CAMERA_ERROR_UNKNOWN, 0);
   10144                             break;
   10145                         }
   10146                         QCameraChannel * pChannel = dw->args.pprocArgs;
   10147                         assert(pChannel);
   10148 
   10149                         if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
   10150                             LOGE("cannot start postprocessor");
   10151                             job_status = BAD_VALUE;
   10152                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10153                                     CAMERA_ERROR_UNKNOWN, 0);
   10154                         }
   10155                     }
   10156                     break;
   10157                 case CMD_DEF_METADATA_ALLOC:
   10158                     {
   10159                         int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
   10160                         if (ret != NO_ERROR) {
   10161                             job_status = ret;
   10162                             LOGE("Metadata alloc failed");
   10163                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10164                                     CAMERA_ERROR_UNKNOWN, 0);
   10165                             break;
   10166                         }
   10167                         pme->mMetadataMem = new QCameraMetadataStreamMemory(
   10168                                 QCAMERA_ION_USE_CACHE);
   10169 
   10170                         if (pme->mMetadataMem == NULL) {
   10171                             LOGE("Unable to allocate metadata buffers");
   10172                             job_status = BAD_VALUE;
   10173                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10174                                     CAMERA_ERROR_UNKNOWN, 0);
   10175                         } else {
   10176                             int32_t rc = pme->mMetadataMem->allocate(
   10177                                     dw->args.metadataAllocArgs.bufferCnt,
   10178                                     dw->args.metadataAllocArgs.size,
   10179                                     NON_SECURE);
   10180                             if (rc < 0) {
   10181                                 delete pme->mMetadataMem;
   10182                                 pme->mMetadataMem = NULL;
   10183                             }
   10184                         }
   10185                      }
   10186                      break;
   10187                 case CMD_DEF_CREATE_JPEG_SESSION:
   10188                     {
   10189                         QCameraChannel * pChannel = dw->args.pprocArgs;
   10190                         assert(pChannel);
   10191 
   10192                         int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
   10193                         if (ret != NO_ERROR) {
   10194                             job_status = ret;
   10195                             LOGE("Jpeg create failed");
   10196                             break;
   10197                         }
   10198 
   10199                         if (pme->m_postprocessor.createJpegSession(pChannel)
   10200                             != NO_ERROR) {
   10201                             LOGE("cannot create JPEG session");
   10202                             job_status = UNKNOWN_ERROR;
   10203                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10204                                     CAMERA_ERROR_UNKNOWN, 0);
   10205                         }
   10206                     }
   10207                     break;
   10208                 case CMD_DEF_PPROC_INIT:
   10209                     {
   10210                         int32_t rc = NO_ERROR;
   10211 
   10212                         jpeg_encode_callback_t jpegEvtHandle =
   10213                                 dw->args.pprocInitArgs.jpeg_cb;
   10214                         void* user_data = dw->args.pprocInitArgs.user_data;
   10215                         QCameraPostProcessor *postProcessor =
   10216                                 &(pme->m_postprocessor);
   10217                         uint32_t cameraId = pme->mCameraId;
   10218                         cam_capability_t *capability =
   10219                                 gCamCapability[cameraId];
   10220                         cam_padding_info_t padding_info;
   10221                         cam_padding_info_t& cam_capability_padding_info =
   10222                                 capability->padding_info;
   10223 
   10224                         if(!pme->mJpegClientHandle) {
   10225                             rc = pme->initJpegHandle();
   10226                             if (rc != NO_ERROR) {
   10227                                 LOGE("Error!! creating JPEG handle failed");
   10228                                 job_status = UNKNOWN_ERROR;
   10229                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10230                                         CAMERA_ERROR_UNKNOWN, 0);
   10231                                 break;
   10232                             }
   10233                         }
   10234                         LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
   10235 
   10236                         rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
   10237                                 &pme->mJpegMpoHandle,
   10238                                 pme->mJpegClientHandle);
   10239                         if (rc != 0) {
   10240                             LOGE("Error!! set JPEG handle failed");
   10241                             job_status = UNKNOWN_ERROR;
   10242                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10243                                     CAMERA_ERROR_UNKNOWN, 0);
   10244                             break;
   10245                         }
   10246 
   10247                         /* get max pic size for jpeg work buf calculation*/
   10248                         rc = postProcessor->init(jpegEvtHandle, user_data);
   10249 
   10250                         if (rc != NO_ERROR) {
   10251                             LOGE("cannot init postprocessor");
   10252                             job_status = UNKNOWN_ERROR;
   10253                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10254                                     CAMERA_ERROR_UNKNOWN, 0);
   10255                             break;
   10256                         }
   10257 
   10258                         // update padding info from jpeg
   10259                         postProcessor->getJpegPaddingReq(padding_info);
   10260                         if (cam_capability_padding_info.width_padding <
   10261                                 padding_info.width_padding) {
   10262                             cam_capability_padding_info.width_padding =
   10263                                     padding_info.width_padding;
   10264                         }
   10265                         if (cam_capability_padding_info.height_padding <
   10266                                 padding_info.height_padding) {
   10267                             cam_capability_padding_info.height_padding =
   10268                                     padding_info.height_padding;
   10269                         }
   10270                         if (cam_capability_padding_info.plane_padding !=
   10271                                 padding_info.plane_padding) {
   10272                             cam_capability_padding_info.plane_padding =
   10273                                     mm_stream_calc_lcm(
   10274                                     cam_capability_padding_info.plane_padding,
   10275                                     padding_info.plane_padding);
   10276                         }
   10277                         if (cam_capability_padding_info.offset_info.offset_x
   10278                                 != padding_info.offset_info.offset_x) {
   10279                             cam_capability_padding_info.offset_info.offset_x =
   10280                                     mm_stream_calc_lcm (
   10281                                     cam_capability_padding_info.offset_info.offset_x,
   10282                                     padding_info.offset_info.offset_x);
   10283                         }
   10284                         if (cam_capability_padding_info.offset_info.offset_y
   10285                                 != padding_info.offset_info.offset_y) {
   10286                             cam_capability_padding_info.offset_info.offset_y =
   10287                             mm_stream_calc_lcm (
   10288                                     cam_capability_padding_info.offset_info.offset_y,
   10289                                     padding_info.offset_info.offset_y);
   10290                         }
   10291                     }
   10292                     break;
   10293                 case CMD_DEF_PARAM_ALLOC:
   10294                     {
   10295                         int32_t rc = NO_ERROR;
   10296                         if (pme->isDualCamera()) {
   10297                             rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
   10298                         } else {
   10299                             rc = pme->mParameters.allocate();
   10300                         }
   10301                         // notify routine would not be initialized by this time.
   10302                         // So, just update error job status
   10303                         if (rc != NO_ERROR) {
   10304                             job_status = rc;
   10305                             LOGE("Param allocation failed");
   10306                             break;
   10307                         }
   10308                     }
   10309                     break;
   10310                 case CMD_DEF_PARAM_INIT:
   10311                     {
   10312                         int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
   10313                         if (rc != NO_ERROR) {
   10314                             job_status = rc;
   10315                             LOGE("Param init failed");
   10316                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10317                                     CAMERA_ERROR_UNKNOWN, 0);
   10318                             break;
   10319                         }
   10320 
   10321                         uint32_t camId = pme->mCameraId;
   10322                         cam_capability_t * cap = gCamCapability[camId];
   10323 
   10324                         if (pme->mCameraHandle == NULL) {
   10325                             LOGE("Camera handle is null");
   10326                             job_status = BAD_VALUE;
   10327                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10328                                     CAMERA_ERROR_UNKNOWN, 0);
   10329                             break;
   10330                         }
   10331 
   10332                         // Now PostProc need calibration data as initialization
   10333                         // time for jpeg_open and calibration data is a
   10334                         // get param for now, so params needs to be initialized
   10335                         // before postproc init
   10336                         rc = pme->mParameters.init(cap,
   10337                                 pme->mCameraHandle,
   10338                                 pme);
   10339                         if (rc != 0) {
   10340                             job_status = UNKNOWN_ERROR;
   10341                             LOGE("Parameter Initialization failed");
   10342                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10343                                     CAMERA_ERROR_UNKNOWN, 0);
   10344                             break;
   10345                         }
   10346 
   10347                         // Get related cam calibration only in
   10348                         // dual camera mode
   10349                         if (pme->getRelatedCamSyncInfo()->sync_control ==
   10350                                 CAM_SYNC_RELATED_SENSORS_ON) {
   10351                             rc = pme->mParameters.getRelatedCamCalibration(
   10352                                 &(pme->mJpegMetadata.otp_calibration_data));
   10353                             LOGD("Dumping Calibration Data Version Id %f rc %d",
   10354                                     pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
   10355                                     rc);
   10356                             if (rc != 0) {
   10357                                 job_status = UNKNOWN_ERROR;
   10358                                 LOGE("getRelatedCamCalibration failed");
   10359                                 pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10360                                         CAMERA_ERROR_UNKNOWN, 0);
   10361                                 break;
   10362                             }
   10363                             pme->m_bRelCamCalibValid = true;
   10364                         }
   10365 
   10366                         pme->mJpegMetadata.sensor_mount_angle =
   10367                             cap->sensor_mount_angle;
   10368                         pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
   10369 
   10370                         pme->mParameters.setMinPpMask(
   10371                             cap->qcom_supported_feature_mask);
   10372                         pme->mExifParams.debug_params =
   10373                                 (mm_jpeg_debug_exif_params_t *)
   10374                                 malloc(sizeof(mm_jpeg_debug_exif_params_t));
   10375                         if (!pme->mExifParams.debug_params) {
   10376                             LOGE("Out of Memory. Allocation failed for "
   10377                                     "3A debug exif params");
   10378                             job_status = NO_MEMORY;
   10379                             pme->sendEvtNotify(CAMERA_MSG_ERROR,
   10380                                     CAMERA_ERROR_UNKNOWN, 0);
   10381                             break;
   10382                         }
   10383                         memset(pme->mExifParams.debug_params, 0,
   10384                                 sizeof(mm_jpeg_debug_exif_params_t));
   10385                     }
   10386                     break;
   10387                 case CMD_DEF_GENERIC:
   10388                     {
   10389                         BackgroundTask *bgTask = dw->args.genericArgs;
   10390                         job_status = bgTask->bgFunction(bgTask->bgArgs);
   10391                     }
   10392                     break;
   10393                 default:
   10394                     LOGE("Incorrect command : %d", dw->cmd);
   10395                 }
   10396 
   10397                 pme->dequeueDeferredWork(dw, job_status);
   10398             }
   10399             break;
   10400         case CAMERA_CMD_TYPE_EXIT:
   10401             running = 0;
   10402             break;
   10403         default:
   10404             break;
   10405         }
   10406     } while (running);
   10407 
   10408     return NULL;
   10409 }
   10410 
   10411 /*===========================================================================
   10412  * FUNCTION   : queueDeferredWork
   10413  *
   10414  * DESCRIPTION: function which queues deferred tasks
   10415  *
   10416  * PARAMETERS :
   10417  *   @cmd     : deferred task
   10418  *   @args    : deferred task arguments
   10419  *
   10420  * RETURN     : job id of deferred job
   10421  *            : 0 in case of error
   10422  *==========================================================================*/
   10423 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
   10424                                                       DeferWorkArgs args)
   10425 {
   10426     Mutex::Autolock l(mDefLock);
   10427     for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
   10428         if (mDefOngoingJobs[i].mDefJobId == 0) {
   10429             DefWork *dw = new DefWork(cmd, sNextJobId, args);
   10430             if (!dw) {
   10431                 LOGE("out of memory.");
   10432                 return 0;
   10433             }
   10434             if (mCmdQueue.enqueue(dw)) {
   10435                 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
   10436                 mDefOngoingJobs[i].mDefJobStatus = 0;
   10437                 if (sNextJobId == 0) { // handle overflow
   10438                     sNextJobId = 1;
   10439                 }
   10440                 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
   10441                         FALSE,
   10442                         FALSE);
   10443                 return mDefOngoingJobs[i].mDefJobId;
   10444             } else {
   10445                 LOGD("Command queue not active! cmd = %d", cmd);
   10446                 delete dw;
   10447                 return 0;
   10448             }
   10449         }
   10450     }
   10451     return 0;
   10452 }
   10453 
   10454 /*===========================================================================
   10455  * FUNCTION   : initJpegHandle
   10456  *
   10457  * DESCRIPTION: Opens JPEG client and gets a handle.
   10458  *                     Sends Dual cam calibration info if present
   10459  *
   10460  * RETURN     : int32_t type of status
   10461  *              NO_ERROR  -- success
   10462  *              none-zero failure code
   10463  *==========================================================================*/
   10464 int32_t QCamera2HardwareInterface::initJpegHandle() {
   10465     // Check if JPEG client handle is present
   10466     LOGH("E");
   10467     if(!mJpegClientHandle) {
   10468         mm_dimension max_size = {0, 0};
   10469         cam_dimension_t size;
   10470 
   10471         mParameters.getMaxPicSize(size);
   10472         max_size.w = size.width;
   10473         max_size.h = size.height;
   10474 
   10475         if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
   10476             if (m_bRelCamCalibValid) {
   10477                 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
   10478                         max_size, &mJpegMetadata);
   10479             } else {
   10480                 mJpegClientHandle =  jpeg_open(&mJpegHandle, &mJpegMpoHandle,
   10481                         max_size, NULL);
   10482             }
   10483         } else {
   10484             mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
   10485         }
   10486         if (!mJpegClientHandle) {
   10487             LOGE("Error !! jpeg_open failed!! ");
   10488             return UNKNOWN_ERROR;
   10489         }
   10490         // Set JPEG initialized as true to signify that this camera
   10491         // has initialized the handle
   10492         mJpegHandleOwner = true;
   10493     }
   10494     LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
   10495              mJpegHandleOwner, mJpegClientHandle, mCameraId);
   10496     return NO_ERROR;
   10497 }
   10498 
   10499 /*===========================================================================
   10500  * FUNCTION   : deinitJpegHandle
   10501  *
   10502  * DESCRIPTION: Closes JPEG client using handle
   10503  *
   10504  * RETURN     : int32_t type of status
   10505  *              NO_ERROR  -- success
   10506  *              none-zero failure code
   10507  *==========================================================================*/
   10508 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
   10509     int32_t rc = NO_ERROR;
   10510     LOGH("E");
   10511     // Check if JPEG client handle is present and inited by this camera
   10512     if(mJpegHandleOwner && mJpegClientHandle) {
   10513         rc = mJpegHandle.close(mJpegClientHandle);
   10514         if (rc != NO_ERROR) {
   10515             LOGE("Error!! Closing mJpegClientHandle: %d failed",
   10516                      mJpegClientHandle);
   10517         }
   10518         memset(&mJpegHandle, 0, sizeof(mJpegHandle));
   10519         memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
   10520         mJpegHandleOwner = false;
   10521     }
   10522     mJpegClientHandle = 0;
   10523     LOGH("X rc = %d", rc);
   10524     return rc;
   10525 }
   10526 
   10527 /*===========================================================================
   10528  * FUNCTION   : setJpegHandleInfo
   10529  *
   10530  * DESCRIPTION: sets JPEG client handle info
   10531  *
   10532  * PARAMETERS:
   10533  *                  @ops                    : JPEG ops
   10534  *                  @mpo_ops             : Jpeg MPO ops
   10535  *                  @pJpegClientHandle : o/p Jpeg Client Handle
   10536  *
   10537  * RETURN     : int32_t type of status
   10538  *              NO_ERROR  -- success
   10539  *              none-zero failure code
   10540  *==========================================================================*/
   10541 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
   10542         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
   10543 
   10544     if (pJpegClientHandle && ops && mpo_ops) {
   10545         LOGH("Setting JPEG client handle %d",
   10546                 pJpegClientHandle);
   10547         memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
   10548         memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
   10549         mJpegClientHandle = pJpegClientHandle;
   10550         return NO_ERROR;
   10551     }
   10552     else {
   10553         LOGE("Error!! No Handle found: %d",
   10554                 pJpegClientHandle);
   10555         return BAD_VALUE;
   10556     }
   10557 }
   10558 
   10559 /*===========================================================================
   10560  * FUNCTION   : getJpegHandleInfo
   10561  *
   10562  * DESCRIPTION: gets JPEG client handle info
   10563  *
   10564  * PARAMETERS:
   10565  *                  @ops                    : JPEG ops
   10566  *                  @mpo_ops             : Jpeg MPO ops
   10567  *                  @pJpegClientHandle : o/p Jpeg Client Handle
   10568  *
   10569  * RETURN     : int32_t type of status
   10570  *              NO_ERROR  -- success
   10571  *              none-zero failure code
   10572  *==========================================================================*/
   10573 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
   10574         mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
   10575 
   10576     if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
   10577         LOGE("Init PProc Deferred work failed");
   10578         return UNKNOWN_ERROR;
   10579     }
   10580     // Copy JPEG ops if present
   10581     if (ops && mpo_ops && pJpegClientHandle) {
   10582         memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
   10583         memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
   10584         *pJpegClientHandle = mJpegClientHandle;
   10585         LOGH("Getting JPEG client handle %d",
   10586                 pJpegClientHandle);
   10587         return NO_ERROR;
   10588     } else {
   10589         return BAD_VALUE;
   10590     }
   10591 }
   10592 
   10593 /*===========================================================================
   10594  * FUNCTION   : dequeueDeferredWork
   10595  *
   10596  * DESCRIPTION: function which dequeues deferred tasks
   10597  *
   10598  * PARAMETERS :
   10599  *   @dw      : deferred work
   10600  *   @jobStatus: deferred task job status
   10601  *
   10602  * RETURN     : int32_t type of status
   10603  *              NO_ERROR  -- success
   10604  *              none-zero failure code
   10605  *==========================================================================*/
   10606 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
   10607 {
   10608     Mutex::Autolock l(mDefLock);
   10609     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   10610         if (mDefOngoingJobs[i].mDefJobId == dw->id) {
   10611             if (jobStatus != NO_ERROR) {
   10612                 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
   10613                 LOGH("updating job status %d for id %d",
   10614                          jobStatus, dw->id);
   10615             } else {
   10616                 mDefOngoingJobs[i].mDefJobId = 0;
   10617                 mDefOngoingJobs[i].mDefJobStatus = 0;
   10618             }
   10619             delete dw;
   10620             mDefCond.broadcast();
   10621             return NO_ERROR;
   10622         }
   10623     }
   10624 
   10625     return UNKNOWN_ERROR;
   10626 }
   10627 
   10628 /*===========================================================================
   10629  * FUNCTION   : getDefJobStatus
   10630  *
   10631  * DESCRIPTION: Gets if a deferred task is success/fail
   10632  *
   10633  * PARAMETERS :
   10634  *   @job_id  : deferred task id
   10635  *
   10636  * RETURN     : NO_ERROR if the job success, otherwise false
   10637  *
   10638  * PRECONDITION : mDefLock is held by current thread
   10639  *==========================================================================*/
   10640 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
   10641 {
   10642     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   10643         if (mDefOngoingJobs[i].mDefJobId == job_id) {
   10644             if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
   10645                 LOGE("job_id (%d) was failed", job_id);
   10646                 return mDefOngoingJobs[i].mDefJobStatus;
   10647             }
   10648             else
   10649                 return NO_ERROR;
   10650         }
   10651     }
   10652     return NO_ERROR;
   10653 }
   10654 
   10655 
   10656 /*===========================================================================
   10657  * FUNCTION   : checkDeferredWork
   10658  *
   10659  * DESCRIPTION: checks if a deferred task is in progress
   10660  *
   10661  * PARAMETERS :
   10662  *   @job_id  : deferred task id
   10663  *
   10664  * RETURN     : true if the task exists, otherwise false
   10665  *
   10666  * PRECONDITION : mDefLock is held by current thread
   10667  *==========================================================================*/
   10668 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
   10669 {
   10670     for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
   10671         if (mDefOngoingJobs[i].mDefJobId == job_id) {
   10672             return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
   10673         }
   10674     }
   10675     return false;
   10676 }
   10677 
   10678 /*===========================================================================
   10679  * FUNCTION   : waitDeferredWork
   10680  *
   10681  * DESCRIPTION: waits for a deferred task to finish
   10682  *
   10683  * PARAMETERS :
   10684  *   @job_id  : deferred task id
   10685  *
   10686  * RETURN     : int32_t type of status
   10687  *              NO_ERROR  -- success
   10688  *              none-zero failure code
   10689  *==========================================================================*/
   10690 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
   10691 {
   10692     Mutex::Autolock l(mDefLock);
   10693 
   10694     if (job_id == 0) {
   10695         LOGD("Invalid job id %d", job_id);
   10696         return NO_ERROR;
   10697     }
   10698 
   10699     while (checkDeferredWork(job_id) == true ) {
   10700         mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
   10701     }
   10702     return getDefJobStatus(job_id);
   10703 }
   10704 
   10705 /*===========================================================================
   10706  * FUNCTION   : scheduleBackgroundTask
   10707  *
   10708  * DESCRIPTION: Run a requested task in the deferred thread
   10709  *
   10710  * PARAMETERS :
   10711  *   @bgTask  : Task to perform in the background
   10712  *
   10713  * RETURN     : job id of deferred job
   10714  *            : 0 in case of error
   10715  *==========================================================================*/
   10716 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
   10717 {
   10718     DeferWorkArgs args;
   10719     memset(&args, 0, sizeof(DeferWorkArgs));
   10720     args.genericArgs = bgTask;
   10721 
   10722     return queueDeferredWork(CMD_DEF_GENERIC, args);
   10723 }
   10724 
   10725 /*===========================================================================
   10726  * FUNCTION   : waitForBackgroundTask
   10727  *
   10728  * DESCRIPTION: Wait for a background task to complete
   10729  *
   10730  * PARAMETERS :
   10731  *   @taskId  : Task id to wait for
   10732  *
   10733  * RETURN     : int32_t type of status
   10734  *              NO_ERROR  -- success
   10735  *              none-zero failure code
   10736  *==========================================================================*/
   10737 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
   10738 {
   10739     return waitDeferredWork(taskId);
   10740 }
   10741 
   10742 /*===========================================================================
   10743  * FUNCTION   : needDeferedAllocation
   10744  *
   10745  * DESCRIPTION: Function to decide background task for streams
   10746  *
   10747  * PARAMETERS :
   10748  *   @stream_type  : stream type
   10749  *
   10750  * RETURN     : true - if background task is needed
   10751  *              false -  if background task is NOT needed
   10752  *==========================================================================*/
   10753 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
   10754 {
   10755     if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
   10756             || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
   10757         return FALSE;
   10758     }
   10759 
   10760     if ((stream_type == CAM_STREAM_TYPE_RAW)
   10761             && (mParameters.getofflineRAW())) {
   10762         return FALSE;
   10763     }
   10764 
   10765     if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
   10766             && (!mParameters.getRecordingHintValue())){
   10767         return TRUE;
   10768     }
   10769 
   10770     if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
   10771             || (stream_type == CAM_STREAM_TYPE_METADATA)
   10772             || (stream_type == CAM_STREAM_TYPE_RAW)
   10773             || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
   10774         return TRUE;
   10775     }
   10776 
   10777     if (stream_type == CAM_STREAM_TYPE_VIDEO) {
   10778         return FALSE;
   10779     }
   10780     return FALSE;
   10781 }
   10782 
   10783 /*===========================================================================
   10784  * FUNCTION   : isRegularCapture
   10785  *
   10786  * DESCRIPTION: Check configuration for regular catpure
   10787  *
   10788  * PARAMETERS :
   10789  *
   10790  * RETURN     : true - regular capture
   10791  *              false - other type of capture
   10792  *==========================================================================*/
   10793 bool QCamera2HardwareInterface::isRegularCapture()
   10794 {
   10795     bool ret = false;
   10796 
   10797     if (numOfSnapshotsExpected() == 1 &&
   10798         !isLongshotEnabled() &&
   10799         !mParameters.isHDREnabled() &&
   10800         !mParameters.getRecordingHintValue() &&
   10801         !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
   10802             ret = true;
   10803     }
   10804     return ret;
   10805 }
   10806 
   10807 /*===========================================================================
   10808  * FUNCTION   : needOfflineReprocessing
   10809  *
   10810  * DESCRIPTION: Check for offline reprocessing
   10811  *
   10812  * PARAMETERS :
   10813  *
   10814  * RETURN     : true - regular capture
   10815  *              false - other type of capture
   10816  *==========================================================================*/
   10817 bool QCamera2HardwareInterface::needOfflineReprocessing()
   10818 {
   10819     bool ret = false;
   10820     if (isRegularCapture()
   10821             || isDualCamera()) {
   10822         ret = true;
   10823     }
   10824     return ret;
   10825 }
   10826 
   10827 /*===========================================================================
   10828  * FUNCTION   : getLogLevel
   10829  *
   10830  * DESCRIPTION: Reads the log level property into a variable
   10831  *
   10832  * PARAMETERS :
   10833  *   None
   10834  *
   10835  * RETURN     :
   10836  *   None
   10837  *==========================================================================*/
   10838 void QCamera2HardwareInterface::getLogLevel()
   10839 {
   10840     char prop[PROPERTY_VALUE_MAX];
   10841 
   10842     property_get("persist.camera.kpi.debug", prop, "1");
   10843     gKpiDebugLevel = atoi(prop);
   10844     return;
   10845 }
   10846 
   10847 /*===========================================================================
   10848  * FUNCTION   : getSensorType
   10849  *
   10850  * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
   10851  *
   10852  * PARAMETERS :
   10853  *   None
   10854  *
   10855  * RETURN     : Type of sensor - bayer or YUV
   10856  *
   10857  *==========================================================================*/
   10858 cam_sensor_t QCamera2HardwareInterface::getSensorType()
   10859 {
   10860     return gCamCapability[mCameraId]->sensor_type.sens_type;
   10861 }
   10862 
   10863 /*===========================================================================
   10864  * FUNCTION   : startRAWChannel
   10865  *
   10866  * DESCRIPTION: start RAW Channel
   10867  *
   10868  * PARAMETERS :
   10869  *   @pChannel  : Src channel to link this RAW channel.
   10870  *
   10871  * RETURN     : int32_t type of status
   10872  *              NO_ERROR  -- success
   10873  *              none-zero failure code
   10874  *==========================================================================*/
   10875 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
   10876 {
   10877     int32_t rc = NO_ERROR;
   10878     QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
   10879     if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
   10880         // Find and try to link a metadata stream from preview channel
   10881         QCameraStream *pMetaStream = NULL;
   10882 
   10883         if (pMetaChannel != NULL) {
   10884             uint32_t streamNum = pMetaChannel->getNumOfStreams();
   10885             QCameraStream *pStream = NULL;
   10886             for (uint32_t i = 0 ; i < streamNum ; i++ ) {
   10887                 pStream = pMetaChannel->getStreamByIndex(i);
   10888                 if ((NULL != pStream) &&
   10889                         (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
   10890                     pMetaStream = pStream;
   10891                     break;
   10892                 }
   10893             }
   10894 
   10895             if (NULL != pMetaStream) {
   10896                 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
   10897                 if (NO_ERROR != rc) {
   10898                     LOGE("Metadata stream link failed %d", rc);
   10899                 }
   10900             }
   10901         }
   10902         rc = pChannel->start();
   10903     }
   10904     return rc;
   10905 }
   10906 
   10907 /*===========================================================================
   10908  * FUNCTION   : startRecording
   10909  *
   10910  * DESCRIPTION: start recording impl
   10911  *
   10912  * PARAMETERS : none
   10913  *
   10914  * RETURN     : int32_t type of status
   10915  *              NO_ERROR  -- success
   10916  *              none-zero failure code
   10917  *==========================================================================*/
   10918 int32_t QCamera2HardwareInterface::stopRAWChannel()
   10919 {
   10920     int32_t rc = NO_ERROR;
   10921     rc = stopChannel(QCAMERA_CH_TYPE_RAW);
   10922     return rc;
   10923 }
   10924 
   10925 /*===========================================================================
   10926  * FUNCTION   : isLowPowerMode
   10927  *
   10928  * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
   10929  *
   10930  * PARAMETERS :
   10931  *   None
   10932  *
   10933  * RETURN     : TRUE/FALSE
   10934  *
   10935  *==========================================================================*/
   10936 bool QCamera2HardwareInterface::isLowPowerMode()
   10937 {
   10938     cam_dimension_t dim;
   10939     mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
   10940 
   10941     char prop[PROPERTY_VALUE_MAX];
   10942     property_get("camera.lowpower.record.enable", prop, "0");
   10943     int enable = atoi(prop);
   10944 
   10945     //Enable low power mode if :
   10946     //1. Video resolution is 2k (2048x1080) or above and
   10947     //2. camera.lowpower.record.enable is set
   10948 
   10949     bool isLowpower = mParameters.getRecordingHintValue() && enable
   10950             && ((dim.width * dim.height) >= (2048 * 1080));
   10951     return isLowpower;
   10952 }
   10953 
   10954 /*===========================================================================
   10955  * FUNCTION   : getBootToMonoTimeOffset
   10956  *
   10957  * DESCRIPTION: Calculate offset that is used to convert from
   10958  *              clock domain of boot to monotonic
   10959  *
   10960  * PARAMETERS :
   10961  *   None
   10962  *
   10963  * RETURN     : clock offset between boottime and monotonic time.
   10964  *
   10965  *==========================================================================*/
   10966 nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset()
   10967 {
   10968     // try three times to get the clock offset, choose the one
   10969     // with the minimum gap in measurements.
   10970     const int tries = 3;
   10971     nsecs_t bestGap, measured;
   10972     for (int i = 0; i < tries; ++i) {
   10973         const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
   10974         const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
   10975         const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
   10976         const nsecs_t gap = tmono2 - tmono;
   10977         if (i == 0 || gap < bestGap) {
   10978             bestGap = gap;
   10979             measured = tbase - ((tmono + tmono2) >> 1);
   10980         }
   10981     }
   10982     return measured;
   10983 }
   10984 
   10985 /*===========================================================================
   10986  * FUNCTION   : fillDualCameraFOVControl
   10987  *
   10988  * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
   10989  *
   10990  * PARAMETERS : none
   10991  *
   10992  * RETURN     : none
   10993  *==========================================================================*/
   10994 void QCamera2HardwareInterface::fillDualCameraFOVControl()
   10995 {
   10996     qcamera_sm_internal_evt_payload_t *payload =
   10997        (qcamera_sm_internal_evt_payload_t *)
   10998        malloc(sizeof(qcamera_sm_internal_evt_payload_t));
   10999     if (NULL != payload) {
   11000         memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
   11001         payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
   11002         int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
   11003         if (rc != NO_ERROR) {
   11004             LOGE("processEvt Dual camera fill FOV control failed");
   11005             free(payload);
   11006             payload = NULL;
   11007         }
   11008     } else {
   11009         LOGE("No memory for Dual camera fill FOV control event");
   11010     }
   11011 }
   11012 
   11013 }; // namespace qcamera
   11014