/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above
*       copyright notice, this list of conditions and the following
*       disclaimer in the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of The Linux Foundation nor the names of its
*       contributors may be used to endorse or promote products derived
*       from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

#define LOG_TAG "QCamera2HWI"

// To remove
#include <cutils/properties.h>

// System definitions
#include <utils/Errors.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include "gralloc_priv.h"
#include "native_handle.h"

// Camera definitions
#include "android/QCamera2External.h"
#include "QCamera2HWI.h"
#include "QCameraBufferMaps.h"
#include "QCameraFlash.h"
#include "QCameraTrace.h"

extern "C" {
#include "mm_camera_dbg.h"
}

#define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \
    ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset)
#define CAMERA_MIN_STREAMING_BUFFERS     3
#define EXTRA_ZSL_PREVIEW_STREAM_BUF     2
#define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
#define CAMERA_MIN_VIDEO_BUFFERS         9
#define CAMERA_MIN_CALLBACK_BUFFERS      5
#define CAMERA_LONGSHOT_STAGES           4
#define CAMERA_MIN_CAMERA_BATCH_BUFFERS  6
#define CAMERA_ISP_PING_PONG_BUFFERS     2
#define MIN_UNDEQUEUED_BUFFERS           1 // This is required if preview window is not set
#define CAMERA_MIN_DISPLAY_BUFFERS       2
#define CAMERA_DEFAULT_FPS               30000

#define HDR_CONFIDENCE_THRESHOLD 0.4

#define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds

// Very long wait, just to be sure we don't deadlock
#define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
#define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
#define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
#define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
#define CAMERA_MAX_PARAM_APPLY_DELAY 3

namespace qcamera {

extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
extern pthread_mutex_t gCamLock;
volatile uint32_t gCamHalLogLevel = 1;
extern uint8_t gNumCameraSessions;
uint32_t QCamera2HardwareInterface::sNextJobId = 1;

camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
    .set_preview_window =        QCamera2HardwareInterface::set_preview_window,
    .set_callbacks =             QCamera2HardwareInterface::set_CallBacks,
    .enable_msg_type =           QCamera2HardwareInterface::enable_msg_type,
    .disable_msg_type =          QCamera2HardwareInterface::disable_msg_type,
    .msg_type_enabled =          QCamera2HardwareInterface::msg_type_enabled,

    .start_preview =             QCamera2HardwareInterface::start_preview,
    .stop_preview =              QCamera2HardwareInterface::stop_preview,
    .preview_enabled =           QCamera2HardwareInterface::preview_enabled,
    .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,

    .start_recording =           QCamera2HardwareInterface::start_recording,
    .stop_recording =            QCamera2HardwareInterface::stop_recording,
    .recording_enabled =         QCamera2HardwareInterface::recording_enabled,
    .release_recording_frame =   QCamera2HardwareInterface::release_recording_frame,

    .auto_focus =                QCamera2HardwareInterface::auto_focus,
    .cancel_auto_focus =         QCamera2HardwareInterface::cancel_auto_focus,

    .take_picture =              QCamera2HardwareInterface::take_picture,
    .cancel_picture =            QCamera2HardwareInterface::cancel_picture,

    .set_parameters =            QCamera2HardwareInterface::set_parameters,
    .get_parameters =            QCamera2HardwareInterface::get_parameters,
    .put_parameters =            QCamera2HardwareInterface::put_parameters,
    .send_command =              QCamera2HardwareInterface::send_command,

    .release =                   QCamera2HardwareInterface::release,
    .dump =                      QCamera2HardwareInterface::dump,
};

/*===========================================================================
 * FUNCTION   : set_preview_window
 *
 * DESCRIPTION: set preview window.
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @window  : window ops table
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
        struct preview_stream_ops *window)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PREVIEW_WINDOW);
    int rc = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d window = %p", hw->getCameraId(), window);

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
    if (rc == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
        rc = apiResult.status;
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

    return rc;
}

/*===========================================================================
 * FUNCTION   : set_CallBacks
 *
 * DESCRIPTION: set callbacks for notify and data
 *
 * PARAMETERS :
 *   @device     : ptr to camera device struct
 *   @notify_cb  : notify cb
 *   @data_cb    : data cb
 *   @data_cb_timestamp  : video data cd with timestamp
 *   @get_memory : ops table for request gralloc memory
 *   @user       : user data ptr
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
        camera_notify_callback notify_cb,
        camera_data_callback data_cb,
        camera_data_timestamp_callback data_cb_timestamp,
        camera_request_memory get_memory,
        void *user)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_CALLBACKS);
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return;
    }
    LOGD("E camera id %d", hw->getCameraId());

    qcamera_sm_evt_setcb_payload_t payload;
    payload.notify_cb = notify_cb;
    payload.data_cb = data_cb;
    payload.data_cb_timestamp = data_cb_timestamp;
    payload.get_memory = get_memory;
    payload.user = user;

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
    if (rc == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

}

/*===========================================================================
 * FUNCTION   : enable_msg_type
 *
 * DESCRIPTION: enable certain msg type
 *
 * PARAMETERS :
 *   @device     : ptr to camera device struct
 *   @msg_type   : msg type mask
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_ENABLE_MSG_TYPE);
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return;
    }
    LOGD("E camera id %d", hw->getCameraId());

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
    if (rc == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

}

/*===========================================================================
 * FUNCTION   : disable_msg_type
 *
 * DESCRIPTION: disable certain msg type
 *
 * PARAMETERS :
 *   @device     : ptr to camera device struct
 *   @msg_type   : msg type mask
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_DISABLE_MSG_TYPE);
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return;
    }
    LOGD("E camera id %d", hw->getCameraId());

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
    if (rc == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

}

/*===========================================================================
 * FUNCTION   : msg_type_enabled
 *
 * DESCRIPTION: if certain msg type is enabled
 *
 * PARAMETERS :
 *   @device     : ptr to camera device struct
 *   @msg_type   : msg type mask
 *
 * RETURN     : 1 -- enabled
 *              0 -- not enabled
 *==========================================================================*/
int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_MSG_TYPE_ENABLED);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
        ret = apiResult.enabled;
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

   return ret;
}

/*===========================================================================
 * FUNCTION   : prepare_preview
 *
 * DESCRIPTION: prepare preview
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_PREVIEW);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
             hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
    ret = hw->processAPI(evt, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(evt, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGH("[KPI Perf]: X");
    return ret;
}


/*===========================================================================
 * FUNCTION   : start_preview
 *
 * DESCRIPTION: start preview
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::start_preview(struct camera_device *device)
{
    KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_PREVIEW);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
             hw->getCameraId());

    hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
    if (hw->isNoDisplayMode()) {
        evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
    }
    ret = hw->processAPI(evt, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(evt, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    hw->m_bPreviewStarted = true;
    LOGI("[KPI Perf]: X ret = %d", ret);
    return ret;
}

/*===========================================================================
 * FUNCTION   : stop_preview
 *
 * DESCRIPTION: stop preview
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
{
    KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_PREVIEW);
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return;
    }
    LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
             hw->getCameraId());

    // Disable power Hint for preview
    hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);

    hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult);
    }
    hw->unlockAPI();
    LOGI("[KPI Perf]: X ret = %d", ret);
}

/*===========================================================================
 * FUNCTION   : preview_enabled
 *
 * DESCRIPTION: if preview is running
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : 1 -- running
 *              0 -- not running
 *==========================================================================*/
int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREVIEW_ENABLED);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult);
        ret = apiResult.enabled;
    }

    //if preview enabled, can enable preview callback send
    if(apiResult.enabled) {
        hw->m_stateMachine.setPreviewCallbackNeeded(true);
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : store_meta_data_in_buffers
 *
 * DESCRIPTION: if need to store meta data in buffers for video frame
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @enable  : flag if enable
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::store_meta_data_in_buffers(
                struct camera_device *device, int enable)
{
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : restart_start_preview
 *
 * DESCRIPTION: start preview as part of the restart preview
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::restart_start_preview(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_START_PREVIEW);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGI("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;

    if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
        ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_START_PREVIEW, NULL);
        if (ret == NO_ERROR) {
            hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_START_PREVIEW, &apiResult);
            ret = apiResult.status;
        }
    } else {
        LOGE("This function is not supposed to be called in single-camera mode");
        ret = INVALID_OPERATION;
    }
    // Preview restart done, update the mPreviewRestartNeeded flag to false.
    hw->mPreviewRestartNeeded = false;
    hw->unlockAPI();
    LOGI("X camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : restart_stop_preview
 *
 * DESCRIPTION: stop preview as part of the restart preview
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::restart_stop_preview(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_STOP_PREVIEW);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGI("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;

    if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
        ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, NULL);
        if (ret == NO_ERROR) {
            hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, &apiResult);
            ret = apiResult.status;
        }
    } else {
        LOGE("This function is not supposed to be called in single-camera mode");
        ret = INVALID_OPERATION;
    }

    hw->unlockAPI();
    LOGI("X camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : pre_start_recording
 *
 * DESCRIPTION: prepare for the start recording
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::pre_start_recording(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_START_RECORDING);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGH("[KPI Perf]: E PROFILE_PRE_START_RECORDING camera id %d",
          hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_PRE_START_RECORDING, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_PRE_START_RECORDING, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGH("[KPI Perf]: X");
    return ret;
}

/*===========================================================================
 * FUNCTION   : start_recording
 *
 * DESCRIPTION: start recording
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::start_recording(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_RECORDING);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }

    hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);

    LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
          hw->getCameraId());
    // Give HWI control to call pre_start_recording in single camera mode.
    // In dual-cam mode, this control belongs to muxer.
    if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
        ret = pre_start_recording(device);
        if (ret != NO_ERROR) {
            LOGE("pre_start_recording failed with ret = %d", ret);
            hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
            return ret;
        }
    }

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    hw->m_bRecordStarted = true;
    LOGI("[KPI Perf]: X ret = %d", ret);

    return ret;
}

/*===========================================================================
 * FUNCTION   : stop_recording
 *
 * DESCRIPTION: stop recording
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_RECORDING);
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return;
    }

    hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);

    LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
             hw->getCameraId());

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
    }
    hw->unlockAPI();
    LOGI("[KPI Perf]: X ret = %d", ret);
}

/*===========================================================================
 * FUNCTION   : recording_enabled
 *
 * DESCRIPTION: if recording is running
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : 1 -- running
 *              0 -- not running
 *==========================================================================*/
int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RECORDING_ENABLED);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
        ret = apiResult.enabled;
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : release_recording_frame
 *
 * DESCRIPTION: return recording frame back
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @opaque  : ptr to frame to be returned
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::release_recording_frame(
            struct camera_device *device, const void *opaque)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REL_REC_FRAME);
    int32_t ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return;
    }
    if (!opaque) {
        LOGE("Error!! Frame info is NULL");
        return;
    }
    LOGD("E camera id %d", hw->getCameraId());

    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
    }
    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());
}

/*===========================================================================
 * FUNCTION   : auto_focus
 *
 * DESCRIPTION: start auto focus
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
{
    KPI_ATRACE_INT("Camera:AutoFocus", 1);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
             hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGH("[KPI Perf] : X ret = %d", ret);

    return ret;
}

/*===========================================================================
 * FUNCTION   : cancel_auto_focus
 *
 * DESCRIPTION: cancel auto focus
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_AF);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
             hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGH("[KPI Perf] : X ret = %d", ret);
    return ret;
}

/*===========================================================================
 * FUNCTION   : pre_take_picture
 *
 * DESCRIPTION: pre take picture, restart preview if necessary.
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_TAKE_PICTURE);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
          hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGH("[KPI Perf]: X");
    return ret;
}

/*===========================================================================
 * FUNCTION   : take_picture
 *
 * DESCRIPTION: take picture
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::take_picture(struct camera_device *device)
{
    KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_TAKE_PICTURE);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
             hw->getCameraId());

    // Acquire the perf lock for JPEG snapshot only
    if (hw->mParameters.isJpegPictureFormat()) {
        hw->m_perfLockMgr.acquirePerfLock(PERF_LOCK_TAKE_SNAPSHOT);
    }

    qcamera_api_result_t apiResult;

   /** Added support for Retro-active Frames:
     *  takePicture() is called before preparing Snapshot to indicate the
     *  mm-camera-channel to pick up legacy frames even
     *  before LED estimation is triggered.
     */

    LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
           hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
           hw->isLongshotEnabled());

    // Check for Retro-active Frames
    if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
        !hw->isLiveSnapshot() && hw->isZSLMode() &&
        !hw->isHDRMode() && !hw->isLongshotEnabled()) {
        // Set Retro Picture Mode
        hw->setRetroPicture(1);
        hw->m_bLedAfAecLock = 0;
        LOGL("Retro Enabled");

        // Give HWI control to call pre_take_picture in single camera mode.
        // In dual-cam mode, this control belongs to muxer.
        if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
            ret = pre_take_picture(device);
            if (ret != NO_ERROR) {
                LOGE("pre_take_picture failed with ret = %d",ret);
                return ret;
            }
        }

        /* Call take Picture for total number of snapshots required.
             This includes the number of retro frames and normal frames */
        hw->lockAPI();
        ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
        if (ret == NO_ERROR) {
          // Wait for retro frames, before calling prepare snapshot
          LOGD("Wait for Retro frames to be done");
          hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
            ret = apiResult.status;
        }
        /* Unlock API since it is acquired in prepare snapshot seperately */
        hw->unlockAPI();

        /* Prepare snapshot in case LED needs to be flashed */
        LOGD("Start Prepare Snapshot");
        ret = hw->prepare_snapshot(device);
    }
    else {
        hw->setRetroPicture(0);
        // Check if prepare snapshot is done
        if (!hw->mPrepSnapRun) {
            // Ignore the status from prepare_snapshot
            hw->prepare_snapshot(device);
        }

        // Give HWI control to call pre_take_picture in single camera mode.
        // In dual-cam mode, this control belongs to muxer.
        if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
            ret = pre_take_picture(device);
            if (ret != NO_ERROR) {
                LOGE("pre_take_picture failed with ret = %d",ret);
                return ret;
            }
        }

        // Regardless what the result value for prepare_snapshot,
        // go ahead with capture anyway. Just like the way autofocus
        // is handled in capture case
        /* capture */
        LOGL("Capturing normal frames");
        hw->lockAPI();
        ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
        if (ret == NO_ERROR) {
          hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
            ret = apiResult.status;
        }
        hw->unlockAPI();
        if (!hw->isLongshotEnabled()){
            // For longshot mode, we prepare snapshot only once
            hw->mPrepSnapRun = false;
         }
    }
    LOGI("[KPI Perf]: X ret = %d", ret);
    return ret;
}

/*===========================================================================
 * FUNCTION   : cancel_picture
 *
 * DESCRIPTION: cancel current take picture request
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_PICTURE);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
             hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);

    return ret;
}

/*===========================================================================
 * FUNCTION   : set_parameters
 *
 * DESCRIPTION: set camera parameters
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @parms   : string of packed parameters
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
                                              const char *parms)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PARAMETERS);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
        ret = apiResult.status;
    }

    // Give HWI control to restart (if necessary) after set params
    // in single camera mode. In dual-cam mode, this control belongs to muxer.
    if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
        if ((ret == NO_ERROR) && hw->getNeedRestart()) {
            LOGD("stopping after param change");
            ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
            if (ret == NO_ERROR) {
                hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
                ret = apiResult.status;
            }
        }

        if (ret == NO_ERROR) {
            LOGD("committing param change");
            ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
            if (ret == NO_ERROR) {
                hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
                ret = apiResult.status;
            }
        }

        if ((ret == NO_ERROR) && hw->getNeedRestart()) {
            LOGD("restarting after param change");
            ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
            if (ret == NO_ERROR) {
                hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
                ret = apiResult.status;
            }
        }
    }

    hw->unlockAPI();
    LOGD("X camera id %d ret %d", hw->getCameraId(), ret);

    return ret;
}

/*===========================================================================
 * FUNCTION   : stop_after_set_params
 *
 * DESCRIPTION: stop after a set param call, if necessary
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_AFTER_SET_PARAMS);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;

    if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
        ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
        if (ret == NO_ERROR) {
            hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
            ret = apiResult.status;
        }
    } else {
        LOGE("is not supposed to be called in single-camera mode");
        ret = INVALID_OPERATION;
    }

    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : commit_params
 *
 * DESCRIPTION: commit after a set param call
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::commit_params(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_COMMIT_PARAMS);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;

    if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
        ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
        if (ret == NO_ERROR) {
            hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
            ret = apiResult.status;
        }
    } else {
        LOGE("is not supposed to be called in single-camera mode");
        ret = INVALID_OPERATION;
    }

    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : restart_after_set_params
 *
 * DESCRIPTION: restart after a set param call, if necessary
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_AFTER_SET_PARAMS);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;

    if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
        ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
        if (ret == NO_ERROR) {
            hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
            ret = apiResult.status;
        }
    } else {
        LOGE("is not supposed to be called in single-camera mode");
        ret = INVALID_OPERATION;
    }

    hw->unlockAPI();
    LOGD("X camera id %d", hw->getCameraId());
    return ret;
}

/*===========================================================================
 * FUNCTION   : get_parameters
 *
 * DESCRIPTION: query camera parameters
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : packed parameters in a string
 *==========================================================================*/
char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_PARAMETERS);
    char *ret = NULL;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return NULL;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
    if (rc == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
        ret = apiResult.params;
    }
    hw->unlockAPI();
    LOGD("E camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : put_parameters
 *
 * DESCRIPTION: return camera parameters string back to HAL
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @parm    : ptr to parameter string to be returned
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
                                               char *parm)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PUT_PARAMETERS);
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
    }
    hw->unlockAPI();
    LOGD("E camera id %d", hw->getCameraId());
}

/*===========================================================================
 * FUNCTION   : send_command
 *
 * DESCRIPTION: command to be executed
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @cmd     : cmd to be executed
 *   @arg1    : ptr to optional argument1
 *   @arg2    : ptr to optional argument2
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::send_command(struct camera_device *device,
                                            int32_t cmd,
                                            int32_t arg1,
                                            int32_t arg2)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());

    qcamera_sm_evt_command_payload_t payload;
    memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
    payload.cmd = cmd;
    payload.arg1 = arg1;
    payload.arg2 = arg2;
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGD("E camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : send_command_restart
 *
 * DESCRIPTION: restart if necessary after a send_command
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @cmd     : cmd to be executed
 *   @arg1    : ptr to optional argument1
 *   @arg2    : ptr to optional argument2
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
        int32_t cmd,
        int32_t arg1,
        int32_t arg2)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND_RESTART);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
            reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }

    qcamera_sm_evt_command_payload_t payload;
    memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
    payload.cmd = cmd;
    payload.arg1 = arg1;
    payload.arg2 = arg2;
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGD("E camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : release
 *
 * DESCRIPTION: release camera resource
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::release(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RELEASE);
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
    }
    hw->unlockAPI();
    LOGD("E camera id %d", hw->getCameraId());
}

/*===========================================================================
 * FUNCTION   : dump
 *
 * DESCRIPTION: dump camera status
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @fd      : fd for status to be dumped to
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
{
    int ret = NO_ERROR;

    //Log level property is read when "adb shell dumpsys media.camera" is
    //called so that the log level can be controlled without restarting
    //media server
    getLogLevel();
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
        ret = apiResult.status;
    }
    hw->unlockAPI();
    LOGD("E camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : close_camera_device
 *
 * DESCRIPTION: close camera device
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
{
    KPI_ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_HAL1_CLOSECAMERA);
    int ret = NO_ERROR;

    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(
            reinterpret_cast<camera_device_t *>(hw_dev)->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
    delete hw;
    LOGI("[KPI Perf]: X");
    KPI_ATRACE_CAMSCOPE_END(CAMSCOPE_HAL1_CLOSECAMERA);
    CAMSCOPE_DESTROY(CAMSCOPE_SECTION_HAL);
    return ret;
}

/*===========================================================================
 * FUNCTION   : register_face_image
 *
 * DESCRIPTION: register a face image into imaging lib for face authenticatio/
 *              face recognition
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *   @img_ptr : ptr to image buffer
 *   @config  : ptr to config about input image, i.e., format, dimension, and etc.
 *
 * RETURN     : >=0 unique ID of face registerd.
 *              <0  failure.
 *==========================================================================*/
int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
                                                   void *img_ptr,
                                                   cam_pp_offline_src_config_t *config)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REGISTER_FACE_IMAGE);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    LOGD("E camera id %d", hw->getCameraId());
    qcamera_sm_evt_reg_face_payload_t payload;
    memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
    payload.img_ptr = img_ptr;
    payload.config = config;
    hw->lockAPI();
    qcamera_api_result_t apiResult;
    ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
    if (ret == NO_ERROR) {
        hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
        ret = apiResult.handle;
    }
    hw->unlockAPI();
    LOGD("E camera id %d", hw->getCameraId());

    return ret;
}

/*===========================================================================
 * FUNCTION   : prepare_snapshot
 *
 * DESCRIPTION: prepares hardware for snapshot
 *
 * PARAMETERS :
 *   @device  : ptr to camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_SNAPSHOT);
    int ret = NO_ERROR;
    QCamera2HardwareInterface *hw =
        reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
    if (!hw) {
        LOGE("NULL camera device");
        return BAD_VALUE;
    }
    if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
        // For longshot mode, we prepare snapshot only once
        LOGH("prepare snapshot only once ");
        return NO_ERROR;
    }
    LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
             hw->getCameraId());
    hw->lockAPI();
    qcamera_api_result_t apiResult;

    /* Prepare snapshot in case LED needs to be flashed */
    if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
        /* Prepare snapshot in case LED needs to be flashed */
        ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
        if (ret == NO_ERROR) {
          hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
            ret = apiResult.status;
        }
        hw->mPrepSnapRun = true;
    }
    hw->unlockAPI();
    LOGH("[KPI Perf]: X, ret: %d", ret);
    return ret;
}

/*===========================================================================
 * FUNCTION   : QCamera2HardwareInterface
 *
 * DESCRIPTION: constructor of QCamera2HardwareInterface
 *
 * PARAMETERS :
 *   @cameraId  : camera ID
 *
 * RETURN     : none
 *==========================================================================*/
QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
    : mCameraId(cameraId),
      mCameraHandle(NULL),
      mMasterCamera(CAM_TYPE_MAIN),
      mCameraOpened(false),
      mDualCamera(false),
      m_pFovControl(NULL),
      m_bRelCamCalibValid(false),
      mPreviewWindow(NULL),
      mMsgEnabled(0),
      mStoreMetaDataInFrame(0),
      mJpegCb(NULL),
      mCallbackCookie(NULL),
      mJpegCallbackCookie(NULL),
      m_bMpoEnabled(TRUE),
      m_stateMachine(this),
      m_smThreadActive(true),
      m_postprocessor(this),
      m_thermalAdapter(QCameraThermalAdapter::getInstance()),
      m_cbNotifier(this),
      m_perfLockMgr(),
      m_bPreviewStarted(false),
      m_bRecordStarted(false),
      m_currentFocusState(CAM_AF_STATE_INACTIVE),
      mDumpFrmCnt(0U),
      mDumpSkipCnt(0U),
      mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
      mActiveAF(false),
      m_HDRSceneEnabled(false),
      mLongshotEnabled(false),
      mLiveSnapshotThread(0),
      mIntPicThread(0),
      mFlashNeeded(false),
      mFlashConfigured(false),
      mDeviceRotation(0U),
      mCaptureRotation(0U),
      mJpegExifRotation(0U),
      mUseJpegExifRotation(false),
      mIs3ALocked(false),
      mPrepSnapRun(false),
      mZoomLevel(0),
      mPreviewRestartNeeded(false),
      mVFrameCount(0),
      mVLastFrameCount(0),
      mVLastFpsTime(0),
      mVFps(0),
      mPFrameCount(0),
      mPLastFrameCount(0),
      mPLastFpsTime(0),
      mPFps(0),
      mLowLightConfigured(false),
      mInstantAecFrameCount(0),
      m_bIntJpegEvtPending(false),
      m_bIntRawEvtPending(false),
      mReprocJob(0),
      mJpegJob(0),
      mMetadataAllocJob(0),
      mInitPProcJob(0),
      mParamAllocJob(0),
      mParamInitJob(0),
      mOutputCount(0),
      mInputCount(0),
      mAdvancedCaptureConfigured(false),
      mHDRBracketingEnabled(false),
      mNumPreviewFaces(-1),
      mJpegClientHandle(0),
      mJpegHandleOwner(false),
      mMetadataMem(NULL),
      mCACDoneReceived(false),
      m_bNeedRestart(false),
      mBootToMonoTimestampOffset(0),
      bDepthAFCallbacks(true),
      m_bNeedHalPP(FALSE)
{
#ifdef TARGET_TS_MAKEUP
    memset(&mFaceRect, -1, sizeof(mFaceRect));
#endif
    getLogLevel();
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_QCAMERA2HWI);
    mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
    mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
    mCameraDevice.common.close = close_camera_device;
    mCameraDevice.ops = &mCameraOps;
    mCameraDevice.priv = this;

    mDualCamera = is_dual_camera_by_idx(cameraId);

    pthread_mutex_init(&m_lock, NULL);
    pthread_cond_init(&m_cond, NULL);

    m_apiResultList = NULL;

    pthread_mutex_init(&m_evtLock, NULL);
    pthread_cond_init(&m_evtCond, NULL);
    memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));


    pthread_mutex_init(&m_int_lock, NULL);
    pthread_cond_init(&m_int_cond, NULL);

    memset(m_channels, 0, sizeof(m_channels));

    memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));

    memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);

    memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
    memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
    memset(&mJpegHandle, 0, sizeof(mJpegHandle));
    memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));

    mDeferredWorkThread.launch(deferredWorkRoutine, this);
    mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);

    pthread_mutex_init(&mGrallocLock, NULL);
    mEnqueuedBuffers = 0;
    mFrameSkipStart = 0;
    mFrameSkipEnd = 0;
    mLastPreviewFrameID = 0;

    //Load and read GPU library.
    lib_surface_utils = NULL;
    LINK_get_surface_pixel_alignment = NULL;
    mSurfaceStridePadding = CAM_PAD_TO_32;
    lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
    if (lib_surface_utils) {
        *(void **)&LINK_get_surface_pixel_alignment =
                dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
         if (LINK_get_surface_pixel_alignment) {
             mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
         }
         dlclose(lib_surface_utils);
    }
}

/*===========================================================================
 * FUNCTION   : ~QCamera2HardwareInterface
 *
 * DESCRIPTION: destructor of QCamera2HardwareInterface
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
QCamera2HardwareInterface::~QCamera2HardwareInterface()
{
    LOGH("E");

    mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
    mDeferredWorkThread.exit();

    if (mMetadataMem != NULL) {
        delete mMetadataMem;
        mMetadataMem = NULL;
    }

    if (m_pFovControl) {
        delete m_pFovControl;
        m_pFovControl = NULL;
    }

    m_perfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA);
    lockAPI();
    m_smThreadActive = false;
    unlockAPI();
    m_stateMachine.releaseThread();
    closeCamera();
    m_perfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA);

    pthread_mutex_destroy(&m_lock);
    pthread_cond_destroy(&m_cond);
    pthread_mutex_destroy(&m_evtLock);
    pthread_cond_destroy(&m_evtCond);
    pthread_mutex_destroy(&m_int_lock);
    pthread_cond_destroy(&m_int_cond);
    pthread_mutex_destroy(&mGrallocLock);
    LOGH("X");
}

/*===========================================================================
 * FUNCTION   : deferPPInit
 *
 * DESCRIPTION: Queue postproc init task to deferred thread
 *
 * PARAMETERS : none
 *
 * RETURN     : uint32_t job id of pproc init job
 *              0  -- failure
 *==========================================================================*/
uint32_t QCamera2HardwareInterface::deferPPInit()
{
    // init pproc
    DeferWorkArgs args;
    DeferPProcInitArgs pprocInitArgs;

    memset(&args, 0, sizeof(DeferWorkArgs));
    memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));

    pprocInitArgs.jpeg_cb = jpegEvtHandle;
    pprocInitArgs.user_data = this;
    args.pprocInitArgs = pprocInitArgs;

    return queueDeferredWork(CMD_DEF_PPROC_INIT,
            args);
}

/*===========================================================================
 * FUNCTION   : openCamera
 *
 * DESCRIPTION: open camera
 *
 * PARAMETERS :
 *   @hw_device  : double ptr for camera device struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
{
    KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_OPENCAMERA);
    int rc = NO_ERROR;
    if (mCameraOpened) {
        *hw_device = NULL;
        LOGE("Permission Denied");
        return PERMISSION_DENIED;
    }
    LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
            mCameraId);

    m_perfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);

    rc = openCamera();
    if (rc == NO_ERROR){
        *hw_device = &mCameraDevice.common;
        if (m_thermalAdapter.init(this) != 0) {
          LOGW("Init thermal adapter failed");
        }
    }
    else
        *hw_device = NULL;

    LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
            mCameraId, rc);

    return rc;
}

/*===========================================================================
 * FUNCTION   : openCamera
 *
 * DESCRIPTION: open camera
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::openCamera()
{
    int32_t rc = NO_ERROR;
    char value[PROPERTY_VALUE_MAX];

    if (mCameraHandle) {
        LOGE("Failure: Camera already opened");
        return ALREADY_EXISTS;
    }

    rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
    if (rc < 0) {
        LOGE("Failed to reserve flash for camera id: %d",
                mCameraId);
        return UNKNOWN_ERROR;
    }

    // alloc param buffer
    DeferWorkArgs args;
    memset(&args, 0, sizeof(args));
    mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
    if (mParamAllocJob == 0) {
        LOGE("Failed queueing PARAM_ALLOC job");
        return -ENOMEM;
    }

    if (gCamCapability[mCameraId] != NULL) {
        // allocate metadata buffers
        DeferWorkArgs args;
        DeferMetadataAllocArgs metadataAllocArgs;

        memset(&args, 0, sizeof(args));
        memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));

        uint32_t padding =
                gCamCapability[mCameraId]->padding_info.plane_padding;
        metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
                padding);
        metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
        args.metadataAllocArgs = metadataAllocArgs;

        mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
        if (mMetadataAllocJob == 0) {
            LOGE("Failed to allocate metadata buffer");
            rc = -ENOMEM;
            goto error_exit1;
        }

        rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
        if (rc) {
            LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
                     rc, mCameraHandle);
            goto error_exit2;
        }

        mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
                camEvtHandle,
                (void *) this);
    } else {
        LOGH("Capabilities not inited, initializing now.");

        rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
        if (rc) {
            LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
                     rc, mCameraHandle);
            goto error_exit2;
        }

        if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
            LOGE("initCapabilities failed.");
            rc = UNKNOWN_ERROR;
            goto error_exit3;
        }

        mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
                camEvtHandle,
                (void *) this);
    }
    mBundledSnapshot = 0;
    mActiveCameras = MM_CAMERA_TYPE_MAIN;
    if (isDualCamera()) {
        mActiveCameras |= MM_CAMERA_TYPE_AUX;

        // Create and initialize FOV-control object
        m_pFovControl = QCameraFOVControl::create(gCamCapability[mCameraId]->main_cam_cap,
                gCamCapability[mCameraId]->aux_cam_cap);
        if (m_pFovControl) {
            *gCamCapability[mCameraId] = m_pFovControl->consolidateCapabilities(
                    gCamCapability[mCameraId]->main_cam_cap,
                    gCamCapability[mCameraId]->aux_cam_cap);
        } else {
            LOGE("FOV-control: Failed to create an object");
            rc = NO_MEMORY;
            goto error_exit3;
        }
    }

    // Init params in the background
    // 1. It's safe to queue init job, even if alloc job is not yet complete.
    // It will be queued to the same thread, so the alloc is guaranteed to
    // finish first.
    // 2. However, it is not safe to begin param init until after camera is
    // open. That is why we wait until after camera open completes to schedule
    // this task.
    memset(&args, 0, sizeof(args));
    mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
    if (mParamInitJob == 0) {
        LOGE("Failed queuing PARAM_INIT job");
        rc = -ENOMEM;
        goto error_exit3;
    }

    mCameraOpened = true;

    //Notify display HAL that a camera session is active.
    //But avoid calling the same during bootup because camera service might open/close
    //cameras at boot time during its initialization and display service will also internally
    //wait for camera service to initialize first while calling this display API, resulting in a
    //deadlock situation. Since boot time camera open/close calls are made only to fetch
    //capabilities, no need of this display bw optimization.
    //Use "service.bootanim.exit" property to know boot status.
    property_get("service.bootanim.exit", value, "0");
    if (atoi(value) == 1) {
        pthread_mutex_lock(&gCamLock);
        if (gNumCameraSessions++ == 0) {
            setCameraLaunchStatus(true);
        }
        pthread_mutex_unlock(&gCamLock);
    }

    // Setprop to decide the time source (whether boottime or monotonic).
    // By default, use monotonic time.
    property_get("persist.camera.time.monotonic", value, "1");
    mBootToMonoTimestampOffset = 0;
    if (atoi(value) == 1) {
        // if monotonic is set, then need to use time in monotonic.
        // So, Measure the clock offset between BOOTTIME and MONOTONIC
        // The clock domain source for ISP is BOOTTIME and
        // for Video/display is MONOTONIC
        // The below offset is used to convert from clock domain of other subsystem
        // (video/hardware composer) to that of camera. Assumption is that this
        // offset won't change during the life cycle of the camera device. In other
        // words, camera device shouldn't be open during CPU suspend.
        mBootToMonoTimestampOffset = getBootToMonoTimeOffset();
    }
    LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset);

    memset(value, 0, sizeof(value));
    property_get("persist.camera.depth.focus.cb", value, "1");
    bDepthAFCallbacks = atoi(value);

    memset(value, 0, sizeof(value));
    property_get("persist.camera.cache.optimize", value, "1");
    m_bOptimizeCacheOps = atoi(value);

    return NO_ERROR;

error_exit3:
    if(mJpegClientHandle) {
        deinitJpegHandle();
    }
    mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
    mCameraHandle = NULL;
error_exit2:
    waitDeferredWork(mMetadataAllocJob);
error_exit1:
    waitDeferredWork(mParamAllocJob);
    return rc;

}

/*===========================================================================
 * FUNCTION   : bundleRelatedCameras
 *
 * DESCRIPTION: bundle cameras to enable syncing of cameras
 *
 * PARAMETERS :
 *   @sync        :indicates whether syncing is On or Off
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn)
{
    int32_t rc = mParameters.bundleRelatedCameras(syncOn);
    if (rc != NO_ERROR) {
        LOGE("bundleRelatedCameras failed %d", rc);
        return rc;
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : getCameraSessionId
 *
 * DESCRIPTION: gets the backend session Id of this HWI instance
 *
 * PARAMETERS :
 *   @sessionid  : pointer to the output session id
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
{
    int32_t rc = NO_ERROR;

    if(session_id != NULL) {
        rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
                session_id);
        LOGD("Getting Camera Session Id %d", *session_id);
    } else {
        LOGE("Session Id is Null");
        return UNKNOWN_ERROR;
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : isFrameSyncEnabled
 *
 * DESCRIPTION: returns whether frame sync is enabled
 *
 * PARAMETERS : none
 *
 * RETURN     : bool indicating whether frame sync is enabled
 *==========================================================================*/
bool QCamera2HardwareInterface::isFrameSyncEnabled(void)
{
    return mParameters.isFrameSyncEnabled();
}

/*===========================================================================
 * FUNCTION   : setFrameSyncEnabled
 *
 * DESCRIPTION: sets whether frame sync is enabled
 *
 * PARAMETERS :
 *   @enable  : flag whether to enable or disable frame sync
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable)
{
    return mParameters.setFrameSyncEnabled(enable);
}

/*===========================================================================
 * FUNCTION   : getRelatedCamSyncInfo
 *
 * DESCRIPTION:returns the related cam sync info for this HWI instance
 *
 * PARAMETERS :none
 *
 * RETURN     : const pointer to cam_sync_related_sensors_event_info_t
 *==========================================================================*/
const cam_sync_related_sensors_event_info_t*
        QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
{
    return mParameters.getRelatedCamSyncInfo();
}

/*===========================================================================
 * FUNCTION   : setRelatedCamSyncInfo
 *
 * DESCRIPTION:sets the related cam sync info for this HWI instance
 *
 * PARAMETERS :
 *   @info  : ptr to related cam info parameters
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
        cam_sync_related_sensors_event_info_t* info)
{
    if(info) {
        return mParameters.setRelatedCamSyncInfo(info);
    } else {
        return BAD_TYPE;
    }
}

/*===========================================================================
 * FUNCTION   : getMpoComposition
 *
 * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
 *                    or not
 *
 * PARAMETERS :none
 *
 * RETURN     : bool indicates whether mpo composition is enabled or not
 *==========================================================================*/
bool QCamera2HardwareInterface::getMpoComposition(void)
{
    LOGH("MpoComposition:%d ", m_bMpoEnabled);
    return m_bMpoEnabled;
}

/*===========================================================================
 * FUNCTION   : setMpoComposition
 *
 * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
 *
 * PARAMETERS :
 *   @enable  : indicates whether Mpo composition enabled or not
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
{
    // By default set Mpo composition to disable
    m_bMpoEnabled = false;

    // Enable Mpo composition only if
    // 1) frame sync is ON between two cameras and
    // 2) any advanced features are not enabled (AOST features) and
    // 3) not in recording mode (for liveshot case)
    // 4) flash is not needed
    if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
            !mParameters.isAdvCamFeaturesEnabled() &&
            !mParameters.getRecordingHintValue() &&
            !mFlashNeeded &&
            !isLongshotEnabled()) {
        m_bMpoEnabled = enable;
        LOGH("MpoComposition:%d ", m_bMpoEnabled);
        return NO_ERROR;
    } else {
        return BAD_TYPE;
    }
}

/*===========================================================================
 * FUNCTION   : getRecordingHintValue
 *
 * DESCRIPTION:function to retrieve recording hint value
 *
 * PARAMETERS :none
 *
 * RETURN     : bool indicates whether recording hint is enabled or not
 *==========================================================================*/
bool QCamera2HardwareInterface::getRecordingHintValue(void)
{
    return mParameters.getRecordingHintValue();
}

/*===========================================================================
 * FUNCTION   : setRecordingHintValue
 *
 * DESCRIPTION:set recording hint value
 *
 * PARAMETERS :
 *   @enable  : video hint value
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
{
    return mParameters.updateRecordingHintValue(value);
}

/*===========================================================================
 * FUNCTION   : closeCamera
 *
 * DESCRIPTION: close camera
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::closeCamera()
{
    int rc = NO_ERROR;
    int i;
    char value[PROPERTY_VALUE_MAX];
    LOGI("E");
    if (!mCameraOpened) {
        return NO_ERROR;
    }
    LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
             mCameraId);

    // set open flag to false
    mCameraOpened = false;

    // Reset Stream config info
    mParameters.setStreamConfigure(false, false, true);

    // deinit Parameters
    mParameters.deinit();

    // exit notifier
    m_cbNotifier.exit();

    // stop and deinit postprocessor
    waitDeferredWork(mReprocJob);
    // Close the JPEG session
    waitDeferredWork(mJpegJob);
    m_postprocessor.stop();
    deinitJpegHandle();
    m_postprocessor.deinit();
    mInitPProcJob = 0; // reset job id, so pproc can be reinited later

    m_thermalAdapter.deinit();

    // delete all channels if not already deleted
    for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
        if (m_channels[i] != NULL) {
            m_channels[i]->stop();
            delete m_channels[i];
            m_channels[i] = NULL;
        }
    }

    //free all pending api results here
    if(m_apiResultList != NULL) {
        api_result_list *apiResultList = m_apiResultList;
        api_result_list *apiResultListNext;
        while (apiResultList != NULL) {
            apiResultListNext = apiResultList->next;
            free(apiResultList);
            apiResultList = apiResultListNext;
        }
    }

    rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
    mCameraHandle = NULL;

    //Notify display HAL that there is no active camera session
    //but avoid calling the same during bootup. Refer to openCamera
    //for more details.
    property_get("service.bootanim.exit", value, "0");
    if (atoi(value) == 1) {
        pthread_mutex_lock(&gCamLock);
        if (--gNumCameraSessions == 0) {
            setCameraLaunchStatus(false);
        }
        pthread_mutex_unlock(&gCamLock);
    }

    if (mExifParams.debug_params) {
        free(mExifParams.debug_params);
        mExifParams.debug_params = NULL;
    }

    if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
        LOGD("Failed to release flash for camera id: %d",
                mCameraId);
    }

    LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
         mCameraId, rc);

    return rc;
}

#define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )


/*===========================================================================
 * FUNCTION   : getCapabilities
 *
 * DESCRIPTION: query camera capability from back-end
 *
 * PARAMETERS :
 *   @ops        : mm-interface ops structure
 *   @cam_handle  : camera handle for which we need capability
 *
 * RETURN     : ptr type of capability structure
 *              capability for success
 *              NULL for failure
 *==========================================================================*/
cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
        uint32_t cam_handle)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
    int rc = NO_ERROR;
    QCameraHeapMemory *capabilityHeap = NULL;
    cam_capability_t *cap_ptr = NULL;

    if (ops == NULL) {
        LOGE("Invalid arguments");
        return NULL;
    }

    capabilityHeap = new QCameraHeapMemory(1);
    if (capabilityHeap == NULL) {
        LOGE("creation of capabilityHeap failed");
        return NULL;
    }

    /* Allocate memory for capability buffer */
    rc = capabilityHeap->allocate(1, sizeof(cam_capability_t));
    if(rc != OK) {
        LOGE("No memory for capability");
        goto allocate_failed;
    }

    /* Map memory for capability buffer */
    memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));

    cam_buf_map_type_list bufMapList;
    rc = QCameraBufferMaps::makeSingletonBufMapList(
            CAM_MAPPING_BUF_TYPE_CAPABILITY,
            0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
            0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
            bufMapList, capabilityHeap->getPtr(0));

    if (rc == NO_ERROR) {
        rc = ops->map_bufs(cam_handle,
                &bufMapList);
    }
    if(rc < 0) {
        LOGE("failed to map capability buffer");
        goto map_failed;
    }

    /* Query Capability */
    rc = ops->query_capability(cam_handle);
    if(rc < 0) {
        LOGE("failed to query capability");
        rc = FAILED_TRANSACTION;
        goto query_failed;
    }

    cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
    if (cap_ptr == NULL) {
        LOGE("out of memory");
        rc = NO_MEMORY;
        goto query_failed;
    }

    memset(cap_ptr, 0, sizeof(cam_capability_t));
    memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));

    int index;
    for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
        cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
        p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
        p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
    }

query_failed:
    ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
map_failed:
    capabilityHeap->deallocate();
allocate_failed:
    delete capabilityHeap;

    if (rc != NO_ERROR) {
        return NULL;
    } else {
        return cap_ptr;
    }
}

/*===========================================================================
 * FUNCTION   : initCapabilities
 *
 * DESCRIPTION: initialize camera capabilities in static data struct
 *
 * PARAMETERS :
 *   @cameraId  : camera Id
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
        mm_camera_vtbl_t *cameraHandle)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_INIT_CAP);
    int rc = 0;
    uint32_t handle = 0;

    rc = camera_open((uint8_t)cameraId, &cameraHandle);
    if (rc) {
        LOGE("camera_open failed. rc = %d", rc);
        goto open_failed;
    }
    if (!cameraHandle) {
        LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
        goto open_failed;
    }

    handle = get_main_camera_handle(cameraHandle->camera_handle);
    gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
    if (gCamCapability[cameraId] == NULL) {
        rc = FAILED_TRANSACTION;
        goto failed_op;
    }

    gCamCapability[cameraId]->camera_index = cameraId;
    if (is_dual_camera_by_idx(cameraId)) {
        handle = get_aux_camera_handle(cameraHandle->camera_handle);
        gCamCapability[cameraId]->aux_cam_cap =
                getCapabilities(cameraHandle->ops, handle);
        if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
            rc = FAILED_TRANSACTION;
            free(gCamCapability[cameraId]);
            goto failed_op;
        }

        // Copy the main camera capability to main_cam_cap struct
        gCamCapability[cameraId]->main_cam_cap =
                (cam_capability_t *)malloc(sizeof(cam_capability_t));
        if (gCamCapability[cameraId]->main_cam_cap == NULL) {
            LOGE("out of memory");
            rc = NO_MEMORY;
            goto failed_op;
        }
        memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId],
                sizeof(cam_capability_t));
    }
failed_op:
    cameraHandle->ops->close_camera(cameraHandle->camera_handle);
    cameraHandle = NULL;
open_failed:
    return rc;
}

/*===========================================================================
 * FUNCTION   : getCapabilities
 *
 * DESCRIPTION: query camera capabilities
 *
 * PARAMETERS :
 *   @cameraId  : camera Id
 *   @info      : camera info struct to be filled in with camera capabilities
 *
 * RETURN     : int type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
        struct camera_info *info, cam_sync_type_t *p_cam_type)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
    int rc = NO_ERROR;
    struct  camera_info *p_info = NULL;
    pthread_mutex_lock(&gCamLock);
    p_info = get_cam_info(cameraId, p_cam_type);
    p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
    p_info->static_camera_characteristics = NULL;
    memcpy(info, p_info, sizeof (struct camera_info));
    pthread_mutex_unlock(&gCamLock);
    return rc;
}

/*===========================================================================
 * FUNCTION   : getCamHalCapabilities
 *
 * DESCRIPTION: get the HAL capabilities structure
 *
 * PARAMETERS :
 *   @cameraId  : camera Id
 *
 * RETURN     : capability structure of respective camera
 *
 *==========================================================================*/
cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
{
    return gCamCapability[mCameraId];
}

/*===========================================================================
 * FUNCTION   : getBufNumForAux
 *
 * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
 *
 * PARAMETERS :
 *   @stream_type  : type of stream
 *
 * RETURN     : number of buffers needed
 * NOTE     :  Based on the use cases and auxillary camera type,
                    we can decide buffer count
 *==========================================================================*/
uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
{
    if (!isDualCamera()) {
        return 0;
    }

    uint8_t bufferCnt = 1;
    switch (stream_type) {
    case CAM_STREAM_TYPE_PREVIEW:
    case CAM_STREAM_TYPE_VIDEO:
    case CAM_STREAM_TYPE_SNAPSHOT:
    case CAM_STREAM_TYPE_METADATA:
    case CAM_STREAM_TYPE_CALLBACK:
    case CAM_STREAM_TYPE_ANALYSIS:
    case CAM_STREAM_TYPE_POSTVIEW:
    case CAM_STREAM_TYPE_RAW:
    case CAM_STREAM_TYPE_OFFLINE_PROC:
    case CAM_STREAM_TYPE_DEFAULT:
    case CAM_STREAM_TYPE_MAX:
        //For wide & tele, we use same buffer count premary and aux streams.
        bufferCnt = getBufNumRequired(stream_type);
        break;
    default:
        break;
    }
    LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
    return bufferCnt;
}

/*===========================================================================
 * FUNCTION   : getBufNumRequired
 *
 * DESCRIPTION: return number of stream buffers needed for given stream type
 *
 * PARAMETERS :
 *   @stream_type  : type of stream
 *
 * RETURN     : number of buffers needed
 *==========================================================================*/
uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
{
    int bufferCnt = 0;
    int minCaptureBuffers = mParameters.getNumOfSnapshots();
    char value[PROPERTY_VALUE_MAX];
    bool raw_yuv = false;
    int persist_cnt = 0;
    int minPrevFps, maxPrevFps;

    int zslQBuffers = mParameters.getZSLQueueDepth();

    int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
                            CAMERA_MIN_JPEG_ENCODING_BUFFERS;

    int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
                       mParameters.getNumOfExtraHDRInBufsIfNeeded() -
                       mParameters.getNumOfExtraHDROutBufsIfNeeded() +
                       mParameters.getNumOfExtraBuffersForImageProc() +
                       EXTRA_ZSL_PREVIEW_STREAM_BUF;

    int minUndequeCount = 0;
    if (!isNoDisplayMode()) {
        if(mPreviewWindow != NULL) {
            if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
                != 0) {
                LOGW("get_min_undequeued_buffer_count  failed");
                //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
                //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
                minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
            }
        } else {
            //preview window might not be set at this point. So, query directly
            //from BufferQueue implementation of gralloc buffers.
            //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
            //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
            minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
        }
        if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
            // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
            // and so change the MACRO as per minUndequeCount
            LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
                     minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
        }
    }

    LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
            "maxStreamBuf = %d minUndequeCount = %d",
            minCaptureBuffers, zslQBuffers, minCircularBufNum,
            maxStreamBuf, minUndequeCount);
    // Get buffer count for the particular stream type
    switch (stream_type) {
    case CAM_STREAM_TYPE_PREVIEW:
        {
            if (mParameters.isZSLMode()) {
                // We need to add two extra streming buffers to add
                // flexibility in forming matched super buf in ZSL queue.
                // with number being 'zslQBuffers + minCircularBufNum'
                // we see preview buffers sometimes get dropped at CPP
                // and super buf is not forming in ZSL Q for long time.

                bufferCnt = zslQBuffers + minCircularBufNum +
                        mParameters.getNumOfExtraBuffersForImageProc() +
                        mParameters.getNumOfExtraBuffersForPreview() +
                        mParameters.getNumOfExtraHDRInBufsIfNeeded();
                if (isDualCamera()) {
                    bufferCnt += zslQBuffers;
                }
            } else {
                bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
                        mParameters.getMaxUnmatchedFramesInQueue() +
                        mParameters.getNumOfExtraBuffersForPreview();
            }
            // ISP allocates native preview buffers and so reducing same from HAL allocation
            if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
                bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;

            // Extra ZSL preview frames are not needed for HFR case.
            // Thumbnail will not be derived from preview for HFR live snapshot case.
            if ((mParameters.getRecordingHintValue() == true)
                    && (!mParameters.isHfrMode())) {
                bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
            }
            //Adding Extra preview buffers for 60FPS usecase.
            mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
            if (maxPrevFps > CAMERA_DEFAULT_FPS) {
                bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
            }

            // Add the display minUndequeCount count on top of camera requirement
            bufferCnt += minUndequeCount;

            property_get("persist.camera.preview_yuv", value, "0");
            persist_cnt = atoi(value);
            if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
                    && (bufferCnt < persist_cnt)) {
                bufferCnt = persist_cnt;
            }
        }
        break;
    case CAM_STREAM_TYPE_POSTVIEW:
        {
            bufferCnt = minCaptureBuffers +
                        mParameters.getMaxUnmatchedFramesInQueue() +
                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
                        mParameters.getNumOfExtraBuffersForImageProc();

            if (bufferCnt > maxStreamBuf) {
                bufferCnt = maxStreamBuf;
            }
            bufferCnt += minUndequeCount;
        }
        break;
    case CAM_STREAM_TYPE_SNAPSHOT:
        {
            if (mParameters.isZSLMode() || mLongshotEnabled) {
                if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
                        !mLongshotEnabled) {
                    // Single ZSL snapshot case
                    bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
                            mParameters.getNumOfExtraBuffersForImageProc();
                } else {
                    // ZSL Burst or Longshot case
                    bufferCnt = zslQBuffers + minCircularBufNum +
                            mParameters.getNumOfExtraBuffersForImageProc();
                }
                if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
                    //ISP allocates native buffers in YUV case
                    bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
                }
                if (isDualCamera()) {
                    bufferCnt += zslQBuffers;
                }
            } else {
                bufferCnt = minCaptureBuffers +
                            mParameters.getNumOfExtraHDRInBufsIfNeeded() -
                            mParameters.getNumOfExtraHDROutBufsIfNeeded() +
                            mParameters.getNumOfExtraBuffersForImageProc();

                if (bufferCnt > maxStreamBuf) {
                    bufferCnt = maxStreamBuf;
                }
            }
        }
        break;
    case CAM_STREAM_TYPE_RAW:
        property_get("persist.camera.raw_yuv", value, "0");
        raw_yuv = atoi(value) > 0 ? true : false;

        if (isRdiMode() || raw_yuv || isSecureMode()) {
            bufferCnt = zslQBuffers + minCircularBufNum;
        } else if (mParameters.isZSLMode()) {
            bufferCnt = zslQBuffers + minCircularBufNum;
            if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
                //ISP allocates native buffers in YUV case
                bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
            }

        } else {
            bufferCnt = minCaptureBuffers +
                        mParameters.getNumOfExtraHDRInBufsIfNeeded() -
                        mParameters.getNumOfExtraHDROutBufsIfNeeded() +
                        mParameters.getNumOfExtraBuffersForImageProc();

            if (bufferCnt > maxStreamBuf) {
                bufferCnt = maxStreamBuf;
            }
        }

        property_get("persist.camera.preview_raw", value, "0");
        persist_cnt = atoi(value);
        if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
                && (bufferCnt < persist_cnt)) {
            bufferCnt = persist_cnt;
        }
        property_get("persist.camera.video_raw", value, "0");
        persist_cnt = atoi(value);
        if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
                && (bufferCnt < persist_cnt)) {
            bufferCnt = persist_cnt;
        }

        break;
    case CAM_STREAM_TYPE_VIDEO:
        {
            if (mParameters.getBufBatchCount()) {
                //Video Buffer in case of HFR or camera batching..
                bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
            } else if (mParameters.getVideoBatchSize()) {
                //Video Buffer count only for HAL to HAL batching.
                bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
                        * mParameters.getVideoBatchSize());
                if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
                    bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
                }
            } else {
                // No batching enabled.
                bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
            }

            bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
            //if its 4K encoding usecase, then add extra buffer
            cam_dimension_t dim;
            mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
            if (is4k2kResolution(&dim)) {
                 //get additional buffer count
                 property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
                 bufferCnt += atoi(value);
            }
        }
        break;
    case CAM_STREAM_TYPE_METADATA:
        {
            if (mParameters.isZSLMode()) {
                // MetaData buffers should be >= (Preview buffers-minUndequeCount)
                bufferCnt = zslQBuffers + minCircularBufNum +
                            mParameters.getNumOfExtraHDRInBufsIfNeeded() -
                            mParameters.getNumOfExtraHDROutBufsIfNeeded() +
                            mParameters.getNumOfExtraBuffersForImageProc() +
                            EXTRA_ZSL_PREVIEW_STREAM_BUF;
                if (isDualCamera()) {
                    bufferCnt += zslQBuffers;
                }
            } else {
                bufferCnt = minCaptureBuffers +
                            mParameters.getNumOfExtraHDRInBufsIfNeeded() -
                            mParameters.getNumOfExtraHDROutBufsIfNeeded() +
                            mParameters.getMaxUnmatchedFramesInQueue() +
                            CAMERA_MIN_STREAMING_BUFFERS +
                            mParameters.getNumOfExtraBuffersForImageProc();

                if (bufferCnt > zslQBuffers + minCircularBufNum) {
                    bufferCnt = zslQBuffers + minCircularBufNum;
                }
            }
            if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
                bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
            }
        }
        break;
    case CAM_STREAM_TYPE_OFFLINE_PROC:
        {
            bufferCnt = minCaptureBuffers;
            // One of the ubifocus buffers is miscellaneous buffer
            if (mParameters.isUbiRefocus()) {
                bufferCnt -= 1;
            }
            if (mLongshotEnabled) {
                bufferCnt = mParameters.getLongshotStages();
            }
        }
        break;
    case CAM_STREAM_TYPE_CALLBACK:
        bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
        break;
    case CAM_STREAM_TYPE_ANALYSIS:
    case CAM_STREAM_TYPE_DEFAULT:
    case CAM_STREAM_TYPE_MAX:
    default:
        bufferCnt = 0;
        break;
    }

    LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
    if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
        LOGW("Buffer count %d for stream type %d exceeds limit %d",
                 bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
        return CAM_MAX_NUM_BUFS_PER_STREAM;
    }

    return (uint8_t)bufferCnt;
}

/*===========================================================================
 * FUNCTION   : getStreamRefCount
 *
 * DESCRIPTION: return number of instance of stream of stream type
 *
 * PARAMETERS :
 *   @stream_type  : type of stream
 *   @cam_type      : Type of camera for this stream
 *
 * RETURN     : number of stream instances
 * NOTE      :  Based on the use cases and auxillary camera type,
                     we can decide stream reference count.
                     For example in wide and tele use case, we duplicate all stream
                     streams from premary to auxillary.
 *==========================================================================*/
uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type,
        uint32_t cam_type)
{
    uint8_t ref_cnt = 1;

    if (cam_type != MM_CAMERA_DUAL_CAM) {
        return ref_cnt;
    }

    switch (stream_type) {
    case CAM_STREAM_TYPE_PREVIEW:
    case CAM_STREAM_TYPE_SNAPSHOT:
    case CAM_STREAM_TYPE_VIDEO:
    case CAM_STREAM_TYPE_METADATA:
    case CAM_STREAM_TYPE_ANALYSIS:
    case CAM_STREAM_TYPE_CALLBACK:
        if (isDualCamera()) {
            ref_cnt++;
        }
        break;
    case CAM_STREAM_TYPE_POSTVIEW:
    case CAM_STREAM_TYPE_RAW:
    case CAM_STREAM_TYPE_OFFLINE_PROC:
    case CAM_STREAM_TYPE_DEFAULT:
    case CAM_STREAM_TYPE_MAX:
    default:
        break;
    }
    return ref_cnt;
}

/*===========================================================================
 * FUNCTION   : getCamHandleForChannel
 *
 * DESCRIPTION: return actual camera handle based on use case
 *
 * PARAMETERS :
 *   @ch_type  : type of channel
 *
 * RETURN     : uint32_t type camera handle
 * NOTE :  Based on the use cases and auxillary camera type, we can decide cam handle for channel.
                 Incase, we want to avoid any channel for auxillary camera, we can decide here
 *==========================================================================*/
uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
{
    uint32_t handle = 0;
    if (!isDualCamera()) {
        return mCameraHandle->camera_handle;
    }

    /*Based on the use case, decide camera handle for channel*/
    switch (ch_type) {
    case QCAMERA_CH_TYPE_ZSL:
    case QCAMERA_CH_TYPE_CAPTURE:
    case QCAMERA_CH_TYPE_PREVIEW:
    case QCAMERA_CH_TYPE_VIDEO:
    case QCAMERA_CH_TYPE_SNAPSHOT:
    case QCAMERA_CH_TYPE_RAW:
    case QCAMERA_CH_TYPE_METADATA:
    case QCAMERA_CH_TYPE_ANALYSIS:
    case QCAMERA_CH_TYPE_CALLBACK:
    case QCAMERA_CH_TYPE_MAX:
    default:
        handle = mCameraHandle->camera_handle;
        break;
    case QCAMERA_CH_TYPE_REPROCESSING:
        if (!mParameters.isDCmAsymmetricSnapMode()) {
            handle = get_main_camera_handle(mCameraHandle->camera_handle);
        } else {
            /*In Asymmetric mode, we create 2 reproc channels. But
                     one stream is added per channel */
            handle = mCameraHandle->camera_handle;
        }
        break;
    }
    return handle;
}

/*===========================================================================
 * FUNCTION   : allocateStreamBuf
 *
 * DESCRIPTION: alocate stream buffers
 *
 * PARAMETERS :
 *   @stream_type  : type of stream
 *   @size         : size of buffer
 *   @stride       : stride of buffer
 *   @scanline     : scanline of buffer
 *   @bufferCnt    : [IN/OUT] minimum num of buffers to be allocated.
 *                   could be modified during allocation if more buffers needed
 *
 * RETURN     : ptr to a memory obj that holds stream buffers.
 *              NULL if failed
 *==========================================================================*/
QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
        cam_stream_type_t stream_type, size_t size, int stride, int scanline,
        uint8_t &bufferCnt)
{
    int rc = NO_ERROR;
    QCameraMemory *mem = NULL;
    bool bCachedMem = QCAMERA_ION_USE_CACHE;
    bool bPoolMem = false;
    char value[PROPERTY_VALUE_MAX];
    property_get("persist.camera.mem.usepool", value, "1");
    if (atoi(value) == 1) {
        bPoolMem = true;
    }

    // Allocate stream buffer memory object
    switch (stream_type) {
    case CAM_STREAM_TYPE_PREVIEW:
        {
            if (isNoDisplayMode()) {
                mem = new QCameraStreamMemory(mGetMemory,
                        mCallbackCookie,
                        bCachedMem,
                        (bPoolMem) ? &m_memoryPool : NULL,
                        stream_type);
            } else {
                cam_dimension_t dim;
                int minFPS, maxFPS;
                QCameraGrallocMemory *grallocMemory = NULL;

                if (isSecureMode()) {
                    grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie, QCAMERA_MEM_TYPE_SECURE);
                }else {
                    grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
                }

                mParameters.getStreamDimension(stream_type, dim);
                /* we are interested only in maxfps here */
                mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
                int usage = 0;
                if(mParameters.isUBWCEnabled()) {
                    cam_format_t fmt;
                    mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
                    if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
                        usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
                    }
                }
                if (grallocMemory) {
                    grallocMemory->setMappable(
                            CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
                    grallocMemory->setWindowInfo(mPreviewWindow,
                            dim.width,dim.height, stride, scanline,
                            mParameters.getPreviewHalPixelFormat(),
                            maxFPS, usage);
                    pthread_mutex_lock(&mGrallocLock);
                    if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
                        mEnqueuedBuffers = (bufferCnt -
                                CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
                    } else {
                        mEnqueuedBuffers = 0;
                    }
                    pthread_mutex_unlock(&mGrallocLock);
                }
                mem = grallocMemory;
            }
        }
        break;
    case CAM_STREAM_TYPE_POSTVIEW:
        {
            if (isNoDisplayMode() || isPreviewRestartEnabled()) {
                mem = new QCameraStreamMemory(mGetMemory, mCallbackCookie, bCachedMem);
            } else {
                cam_dimension_t dim;
                int minFPS, maxFPS;
                QCameraGrallocMemory *grallocMemory =
                        new QCameraGrallocMemory(mGetMemory, mCallbackCookie);

                mParameters.getStreamDimension(stream_type, dim);
                /* we are interested only in maxfps here */
                mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
                if (grallocMemory) {
                    grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
                            dim.height, stride, scanline,
                            mParameters.getPreviewHalPixelFormat(), maxFPS);
                }
                mem = grallocMemory;
            }
        }
        break;
    case CAM_STREAM_TYPE_ANALYSIS:
    case CAM_STREAM_TYPE_SNAPSHOT:
    case CAM_STREAM_TYPE_OFFLINE_PROC:
        mem = new QCameraStreamMemory(mGetMemory,
                mCallbackCookie,
                bCachedMem,
                (bPoolMem) ? &m_memoryPool : NULL,
                stream_type);
        break;
    case CAM_STREAM_TYPE_RAW:
        if(isSecureMode()) {
            mem = new QCameraStreamMemory(mGetMemory,
                    mCallbackCookie,
                    bCachedMem,
                    (bPoolMem) ? &m_memoryPool : NULL,
                    stream_type,
                    QCAMERA_MEM_TYPE_SECURE);
            LOGH("Allocating %d secure buffers of size %d ", bufferCnt, size);
        } else {
            mem = new QCameraStreamMemory(mGetMemory,
                    mCallbackCookie,
                    bCachedMem,
                    (bPoolMem) ? &m_memoryPool : NULL,
                    stream_type);
        }
        break;
    case CAM_STREAM_TYPE_METADATA:
        {
            if (mMetadataMem == NULL) {
                mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
            } else {
                mem = mMetadataMem;
                mMetadataMem = NULL;

                int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
                if (numAdditionalBuffers > 0) {
                    rc = mem->allocateMore(numAdditionalBuffers, size);
                    if (rc != NO_ERROR) {
                        LOGE("Failed to allocate additional buffers, "
                                "but attempting to proceed.");
                    }
                }
                bufferCnt = mem->getCnt();
                // The memory is already allocated  and initialized, so
                // simply return here.
                return mem;
            }
        }
        break;
    case CAM_STREAM_TYPE_VIDEO:
        {
            //Use uncached allocation by default
            if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
                    mParameters.isHighQualityNoiseReductionMode()) {
                bCachedMem = QCAMERA_ION_USE_CACHE;
            }
            else {
                bCachedMem = QCAMERA_ION_USE_NOCACHE;
            }

            QCameraVideoMemory *videoMemory = NULL;
            int usage = 0;
            cam_format_t fmt;

            if (mParameters.getVideoBatchSize()) {
                videoMemory = new QCameraVideoMemory(
                        mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
                if (videoMemory == NULL) {
                    LOGE("Out of memory for video batching obj");
                    return NULL;
                }
                mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
                if (mParameters.isUBWCEnabled() &&
                        (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
                    usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
                }
                videoMemory->setVideoInfo(usage, fmt);
                /*
                *   numFDs = BATCH size
                *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
                */
                rc = videoMemory->allocateMeta(
                        CAMERA_MIN_VIDEO_BATCH_BUFFERS,
                        mParameters.getVideoBatchSize());
                if (rc < 0) {
                    delete videoMemory;
                    return NULL;
                }
            } else {
                videoMemory =
                        new QCameraVideoMemory(mGetMemory, mCallbackCookie, bCachedMem);
                if (videoMemory == NULL) {
                    LOGE("Out of memory for video obj");
                    return NULL;
                }
                mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
                if (mParameters.isUBWCEnabled() &&
                        (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
                    usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
                }
                videoMemory->setVideoInfo(usage, fmt);
            }
            mem = videoMemory;
        }
        break;
    case CAM_STREAM_TYPE_CALLBACK:
        mem = new QCameraStreamMemory(mGetMemory,
                mCallbackCookie,
                bCachedMem,
                (bPoolMem) ? &m_memoryPool : NULL,
                stream_type);
        break;
    case CAM_STREAM_TYPE_DEFAULT:
    case CAM_STREAM_TYPE_MAX:
    default:
        break;
    }
    if (!mem) {
        return NULL;
    }

    if (bufferCnt > 0) {
        rc = mem->allocate(bufferCnt, size);
        if (rc < 0) {
            delete mem;
            return NULL;
        }
        bufferCnt = mem->getCnt();
    }
    LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d mEnqueuedBuffers = %d",
            rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem, mEnqueuedBuffers);
    return mem;
}

/*===========================================================================
 * FUNCTION   : allocateMoreStreamBuf
 *
 * DESCRIPTION: alocate more stream buffers from the memory object
 *
 * PARAMETERS :
 *   @mem_obj      : memory object ptr
 *   @size         : size of buffer
 *   @bufferCnt    : [IN/OUT] additional number of buffers to be allocated.
 *                   output will be the number of total buffers
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
        QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
{
    int rc = NO_ERROR;

    if (bufferCnt > 0) {
        rc = mem_obj->allocateMore(bufferCnt, size);
        bufferCnt = mem_obj->getCnt();
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : allocateMiscBuf
 *
 * DESCRIPTION: alocate miscellaneous buffer
 *
 * PARAMETERS :
 *   @streamInfo  : stream info
 *
 * RETURN     : ptr to a memory obj that holds stream info buffer.
 *              NULL if failed
 *==========================================================================*/
QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
        cam_stream_info_t *streamInfo)
{
    int rc = NO_ERROR;
    uint8_t bufNum = 0;
    size_t bufSize = 0;
    QCameraHeapMemory *miscBuf = NULL;
    cam_feature_mask_t feature_mask =
            streamInfo->reprocess_config.pp_feature_config.feature_mask;

    switch (streamInfo->stream_type) {
    case CAM_STREAM_TYPE_OFFLINE_PROC:
        if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
            bufNum = 1;
            bufSize = mParameters.getTPMaxMetaSize();
        } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
            bufNum = 1;
            bufSize = mParameters.getRefocusMaxMetaSize();
        }
        break;
    default:
        break;
    }

    if (bufNum && bufSize) {
        miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);

        if (!miscBuf) {
            LOGE("Unable to allocate miscBuf object");
            return NULL;
        }

        rc = miscBuf->allocate(bufNum, bufSize);
        if (rc < 0) {
            LOGE("Failed to allocate misc buffer memory");
            delete miscBuf;
            return NULL;
        }
    }

    return miscBuf;
}

/*===========================================================================
 * FUNCTION   : initStreamInfoBuf
 *
 * DESCRIPTION: initialize stream info buffer based on stream type
 *
 * PARAMETERS :
 *   @stream_type  : type of stream
 *   @cam_type      : Camera type in case of dual camera
 *
 * RETURN     : ptr to a memory obj that holds stream info buffer.
 *              NULL if failed
 *==========================================================================*/
int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
            cam_stream_info_t *streamInfo, uint32_t cam_type)
{
    int rc = NO_ERROR;
    int32_t dt = 0;
    int32_t vc = 0;

    memset(streamInfo, 0, sizeof(cam_stream_info_t));
    streamInfo->stream_type = stream_type;
    rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
    rc = mParameters.getStreamDimension(stream_type, streamInfo->dim, cam_type);
    rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
    streamInfo->num_bufs = getBufNumRequired(stream_type);
    streamInfo->buf_cnt = streamInfo->num_bufs;
    streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    streamInfo->is_secure = NON_SECURE;
    // Initialize cache ops
    if (!m_bOptimizeCacheOps) {
        streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_DISABLED;
    } else {
        streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_HONOUR_FLAGS;
    }

    switch (stream_type) {
    case CAM_STREAM_TYPE_SNAPSHOT:
        if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
            mLongshotEnabled) {
            streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
        } else {
            streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
            streamInfo->num_of_burst = (uint8_t)
                    (mParameters.getNumOfSnapshots()
                        + mParameters.getNumOfExtraHDRInBufsIfNeeded()
                        - mParameters.getNumOfExtraHDROutBufsIfNeeded()
                        + mParameters.getNumOfExtraBuffersForImageProc());
        }
        break;
    case CAM_STREAM_TYPE_RAW: {
            char value[PROPERTY_VALUE_MAX];
            bool raw_yuv = false;
            property_get("persist.camera.raw_yuv", value, "0");
            raw_yuv = atoi(value) > 0 ? true : false;
            if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv) || isSecureMode()) {
                streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
            } else {
                streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
                streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
            }
            if (isSecureMode()) {
                streamInfo->is_secure = SECURE;
            } else {
                streamInfo->is_secure = NON_SECURE;
            }
        }
        if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
            mParameters.updateDtVc(&dt, &vc);
            if (dt)
                streamInfo->dt = dt;
            streamInfo->vc = vc;
        }

        break;
    case CAM_STREAM_TYPE_POSTVIEW:
        if (mLongshotEnabled) {
            streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
        } else {
            streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
            streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
                + mParameters.getNumOfExtraHDRInBufsIfNeeded()
                - mParameters.getNumOfExtraHDROutBufsIfNeeded()
                + mParameters.getNumOfExtraBuffersForImageProc());
        }
        break;
    case CAM_STREAM_TYPE_VIDEO:
        streamInfo->dis_enable = mParameters.isDISEnabled();
        if (mParameters.getBufBatchCount()) {
            //Update stream info structure with batch mode info
            streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
            streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
            streamInfo->user_buf_info.size =
                    (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
            cam_fps_range_t pFpsRange;
            mParameters.getHfrFps(pFpsRange);
            streamInfo->user_buf_info.frameInterval =
                    (long)((1000/pFpsRange.video_max_fps) * 1000);
            LOGH("Video Batch Count = %d, interval = %d",
                    streamInfo->user_buf_info.frame_buf_cnt,
                    streamInfo->user_buf_info.frameInterval);
        }
        if (mParameters.getRecordingHintValue()) {
            if(mParameters.isDISEnabled()) {
                streamInfo->is_type = mParameters.getVideoISType();
            } else {
                streamInfo->is_type = IS_TYPE_NONE;
            }
        }
        if (mParameters.isSecureMode()) {
            streamInfo->is_secure = SECURE;
        }
        break;
    case CAM_STREAM_TYPE_PREVIEW:
        if (mParameters.getRecordingHintValue()) {
            if(mParameters.isDISEnabled()) {
                streamInfo->is_type = mParameters.getPreviewISType();
            } else {
                streamInfo->is_type = IS_TYPE_NONE;
            }
        }
        if (isSecureMode()) {
            streamInfo->is_secure = SECURE;
        } else {
            streamInfo->is_secure = NON_SECURE;
        }
        // If SAT enabled, don't add preview stream to Bundled queue
        if (isDualCamera()) {
            char prop[PROPERTY_VALUE_MAX];
            memset(prop, 0, sizeof(prop));
            bool satEnabledFlag = FALSE;
            property_get("persist.camera.sat.enable", prop, "0");
            satEnabledFlag = atoi(prop);
            if (satEnabledFlag) {
                streamInfo->noFrameExpected = 1;
            }
        }
        break;
    case CAM_STREAM_TYPE_ANALYSIS:
        streamInfo->noFrameExpected = 1;
        break;
    case CAM_STREAM_TYPE_METADATA:
        streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_CLEAR_FLAGS;
        break;
    default:
        break;
    }

    // Update feature mask
    mParameters.updatePpFeatureMask(stream_type);

    // Get feature mask
    mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);

    // Update pp config
    if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
        int flipMode = mParameters.getFlipMode(stream_type);
        if (flipMode > 0) {
            streamInfo->pp_config.flip = (uint32_t)flipMode;
        }
    }
    if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
        streamInfo->pp_config.sharpness = mParameters.getSharpness();
    }
    if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
        streamInfo->pp_config.effect = mParameters.getEffectValue();
    }

    if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
        streamInfo->pp_config.denoise2d.denoise_enable = 1;
        streamInfo->pp_config.denoise2d.process_plates =
                mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
    }

    if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
            CAM_STREAM_TYPE_RAW == stream_type))) {
        if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
                CAM_QCOM_FEATURE_CROP)
            streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
        if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
                CAM_QCOM_FEATURE_SCALE)
            streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
    }
    streamInfo->aux_str_info = NULL;

    LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
           stream_type, streamInfo->fmt, streamInfo->dim.width,
           streamInfo->dim.height, streamInfo->num_bufs,
           streamInfo->pp_config.feature_mask,
           streamInfo->is_type);

    return rc;
}

/*===========================================================================
 * FUNCTION   : allocateStreamInfoBuf
 *
 * DESCRIPTION: alocate stream info buffer
 *
 * PARAMETERS :
 *   @stream_type  : type of stream
 *   @bufCount       : stream info buffer count
 *   @cam_type     : Camera type in case of dual camera
 *
 * RETURN     : ptr to a memory obj that holds stream info buffer.
 *              NULL if failed
 *==========================================================================*/
QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
        cam_stream_type_t stream_type, uint8_t bufCount, uint32_t cam_type)
{
    int rc = NO_ERROR;

    QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
    if (!streamInfoBuf) {
        LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
        return NULL;
    }

    if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
        LOGE("buffer count should be lesser than max camera : %d", bufCount);
        return NULL;
    }
    rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t));
    if (rc < 0) {
        LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
        delete streamInfoBuf;
        return NULL;
    }

    for (uint8_t i = 0; i < bufCount; i++) {
        cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
        memset(streamInfo, 0, sizeof(cam_stream_info_t));
        rc = initStreamInfoBuf(stream_type, streamInfo, cam_type);
        if (rc < 0) {
            LOGE("initStreamInfoBuf failed");
            delete streamInfoBuf;
            return NULL;
        }
    }

    cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
    if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
        cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
        streamInfo->aux_str_info = s_streamInfo;
    }

    if (streamInfo->aux_str_info != NULL) {
        /*Update StreamInfo for Aux camera*/
        streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
        streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
        streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
    }
    return streamInfoBuf;
}

/*===========================================================================
 * FUNCTION   : allocateStreamUserBuf
 *
 * DESCRIPTION: allocate user ptr for stream buffers
 *
 * PARAMETERS :
 *   @streamInfo  : stream info structure
 *
 * RETURN     : ptr to a memory obj that holds stream info buffer.
 *                    NULL if failed

 *==========================================================================*/
QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
        cam_stream_info_t *streamInfo)
{
    int rc = NO_ERROR;
    QCameraMemory *mem = NULL;
    int size = 0;

    if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
        LOGE("Stream is not in BATCH mode. Invalid Stream");
        return NULL;
    }

    // Allocate stream user buffer memory object
    switch (streamInfo->stream_type) {
    case CAM_STREAM_TYPE_VIDEO: {
        QCameraVideoMemory *video_mem = new QCameraVideoMemory(
                mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
        if (video_mem == NULL) {
            LOGE("Out of memory for video obj");
            return NULL;
        }

        int usage = 0;
        cam_format_t fmt;
        mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
        if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
            usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
        }
        video_mem->setVideoInfo(usage, fmt);

        /*
        *   numFDs = BATCH size
        *  numInts = 5  // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
        */
        rc = video_mem->allocateMeta(streamInfo->num_bufs,
                mParameters.getBufBatchCount());
        if (rc < 0) {
            LOGE("allocateMeta failed");
            delete video_mem;
            return NULL;
        }
        mem = static_cast<QCameraMemory *>(video_mem);
    }
    break;

    case CAM_STREAM_TYPE_PREVIEW:
    case CAM_STREAM_TYPE_POSTVIEW:
    case CAM_STREAM_TYPE_ANALYSIS:
    case CAM_STREAM_TYPE_SNAPSHOT:
    case CAM_STREAM_TYPE_RAW:
    case CAM_STREAM_TYPE_METADATA:
    case CAM_STREAM_TYPE_OFFLINE_PROC:
    case CAM_STREAM_TYPE_CALLBACK:
        LOGE("Stream type Not supported.for BATCH processing");
    break;

    case CAM_STREAM_TYPE_DEFAULT:
    case CAM_STREAM_TYPE_MAX:
    default:
        break;
    }
    if (!mem) {
        LOGE("Failed to allocate mem");
        return NULL;
    }

    /*Size of this buffer will be number of batch buffer */
    size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
            CAM_PAD_TO_4K);

    LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);

    if (size > 0) {
        // Allocating one buffer for all batch buffers
        rc = mem->allocate(1, size);
        if (rc < 0) {
            delete mem;
            return NULL;
        }
    }
    return mem;
}


/*===========================================================================
 * FUNCTION   : waitForDeferredAlloc
 *
 * DESCRIPTION: Wait for deferred allocation, if applicable
 *              (applicable only for metadata buffers so far)
 *
 * PARAMETERS :
 *   @stream_type  : type of stream to (possibly) wait for
 *
 * RETURN     : None
 *==========================================================================*/
void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
{
    if (stream_type == CAM_STREAM_TYPE_METADATA) {
        waitDeferredWork(mMetadataAllocJob);
    }
}


/*===========================================================================
 * FUNCTION   : setPreviewWindow
 *
 * DESCRIPTION: set preview window impl
 *
 * PARAMETERS :
 *   @window  : ptr to window ops table struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::setPreviewWindow(
        struct preview_stream_ops *window)
{
    mPreviewWindow = window;
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : setCallBacks
 *
 * DESCRIPTION: set callbacks impl
 *
 * PARAMETERS :
 *   @notify_cb  : notify cb
 *   @data_cb    : data cb
 *   @data_cb_timestamp : data cb with time stamp
 *   @get_memory : request memory ops table
 *   @user       : user data ptr
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
                                            camera_data_callback data_cb,
                                            camera_data_timestamp_callback data_cb_timestamp,
                                            camera_request_memory get_memory,
                                            void *user)
{
    mNotifyCb        = notify_cb;
    mDataCb          = data_cb;
    mDataCbTimestamp = data_cb_timestamp;
    mGetMemory       = get_memory;
    mCallbackCookie  = user;
    m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : setJpegCallBacks
 *
 * DESCRIPTION: set JPEG callbacks impl
 *
 * PARAMETERS :
 *   @jpegCb  : Jpeg callback method
 *   @callbackCookie    : callback cookie
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
                                            void *callbackCookie)
{
    LOGH("camera id %d", getCameraId());
    mJpegCb        = jpegCb;
    mJpegCallbackCookie  = callbackCookie;
    m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
}

/*===========================================================================
 * FUNCTION   : enableMsgType
 *
 * DESCRIPTION: enable msg type impl
 *
 * PARAMETERS :
 *   @msg_type  : msg type mask to be enabled
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
{
    int32_t rc = NO_ERROR;

    if (mParameters.isUBWCEnabled()) {
        /*Need Special CALLBACK stream incase application requesting for
              Preview callback  in UBWC case*/
        if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
                (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
            // Start callback channel only when preview/zsl channel is active
            QCameraChannel* previewCh = NULL;
            if (isZSLMode() && (getRecordingHintValue() != true)) {
                previewCh = m_channels[QCAMERA_CH_TYPE_ZSL];
            } else {
                previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW];
            }
            QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK];
            if ((callbackCh != NULL) &&
                    (previewCh != NULL) && previewCh->isActive()) {
                rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
                if (rc != NO_ERROR) {
                    LOGE("START Callback Channel failed");
                }
            }
        }
    }
    mMsgEnabled |= msg_type;
    LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : disableMsgType
 *
 * DESCRIPTION: disable msg type impl
 *
 * PARAMETERS :
 *   @msg_type  : msg type mask to be disabled
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
{
    int32_t rc = NO_ERROR;

    if (mParameters.isUBWCEnabled()) {
        /*STOP CALLBACK STREAM*/
        if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
                (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
            // Stop callback channel only if it is active
            if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) &&
                   (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) {
                rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
                if (rc != NO_ERROR) {
                    LOGE("STOP Callback Channel failed");
                }
            }
        }
    }
    mMsgEnabled &= ~msg_type;
    LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : msgTypeEnabled
 *
 * DESCRIPTION: impl to determine if certain msg_type is enabled
 *
 * PARAMETERS :
 *   @msg_type  : msg type mask
 *
 * RETURN     : 0 -- not enabled
 *              none 0 -- enabled
 *==========================================================================*/
int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
{
    return (mMsgEnabled & msg_type);
}

/*===========================================================================
 * FUNCTION   : msgTypeEnabledWithLock
 *
 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
 *
 * PARAMETERS :
 *   @msg_type  : msg type mask
 *
 * RETURN     : 0 -- not enabled
 *              none 0 -- enabled
 *==========================================================================*/
int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
{
    int enabled = 0;
    lockAPI();
    enabled = mMsgEnabled & msg_type;
    unlockAPI();
    return enabled;
}

/*===========================================================================
 * FUNCTION   : startPreview
 *
 * DESCRIPTION: start preview impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::startPreview()
{
    KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW);
    int32_t rc = NO_ERROR;

    LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
            mParameters.getRecordingHintValue());

    m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);

    updateThermalLevel((void *)&mThermalLevel);

    setDisplayFrameSkip();

    // start preview stream
    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
        rc = startChannel(QCAMERA_CH_TYPE_ZSL);
    } else if (isSecureMode()) {
        if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
            rc = startChannel(QCAMERA_CH_TYPE_RAW);
        }else {
            rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
        }
    } else {
        rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
    }

    if (isDualCamera()) {
        if (rc == NO_ERROR) {
            mParameters.setDeferCamera(CAM_DEFER_PROCESS);
        } else {
            mParameters.setDeferCamera(CAM_DEFER_FLUSH);
        }
    }

    if (rc != NO_ERROR) {
        LOGE("failed to start channels");
        m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
        return rc;
    }

    if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
            && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
        rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
        if (rc != NO_ERROR) {
            LOGE("failed to start callback stream");
            stopChannel(QCAMERA_CH_TYPE_ZSL);
            stopChannel(QCAMERA_CH_TYPE_PREVIEW);
            m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
            return rc;
        }
    }

    updatePostPreviewParameters();
    m_stateMachine.setPreviewCallbackNeeded(true);

    // if job id is non-zero, that means the postproc init job is already
    // pending or complete
    if (mInitPProcJob == 0) {
        mInitPProcJob = deferPPInit();
        if (mInitPProcJob == 0) {
            LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
                     mCameraHandle);
            rc = -ENOMEM;
            m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
            return rc;
        }
    }

    LOGI("X rc = %d", rc);
    return rc;
}

int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
    // Enable OIS only in Camera mode and 4k2k camcoder mode
    int32_t rc = NO_ERROR;
    rc = mParameters.updateOisValue(1);
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : stopPreview
 *
 * DESCRIPTION: stop preview impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::stopPreview()
{
    KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOPPREVIEW);
    LOGI("E");
    mNumPreviewFaces = -1;
    mActiveAF = false;

    // Disable power Hint for preview
    m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);

    m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);

    // stop preview stream
    stopChannel(QCAMERA_CH_TYPE_CALLBACK);
    stopChannel(QCAMERA_CH_TYPE_ZSL);
    stopChannel(QCAMERA_CH_TYPE_PREVIEW);
    stopChannel(QCAMERA_CH_TYPE_RAW);

    m_cbNotifier.flushPreviewNotifications();
    //add for ts makeup
#ifdef TARGET_TS_MAKEUP
    ts_makeup_finish();
#endif
    // delete all channels from preparePreview
    unpreparePreview();

    m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_PREVIEW);
    LOGI("X");
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : storeMetaDataInBuffers
 *
 * DESCRIPTION: enable store meta data in buffers for video frames impl
 *
 * PARAMETERS :
 *   @enable  : flag if need enable
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
{
    mStoreMetaDataInFrame = enable;
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : preStartRecording
 *
 * DESCRIPTION: Prepare start recording impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::preStartRecording()
{
    int32_t rc = NO_ERROR;
    LOGH("E");
    if (mParameters.getRecordingHintValue() == false) {

        // Give HWI control to restart preview only in single camera mode.
        // In dual-cam mode, this control belongs to muxer.
        if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
            LOGH("start recording when hint is false, stop preview first");
            stopPreview();

            // Set recording hint to TRUE
            mParameters.updateRecordingHintValue(TRUE);
            rc = preparePreview();
            if (rc == NO_ERROR) {
                rc = startPreview();
            }
        }
        else
        {
            // For dual cam mode, update the flag mPreviewRestartNeeded to true
            // Restart control will be handled by muxer.
            mPreviewRestartNeeded = true;
        }
    }

    LOGH("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : startRecording
 *
 * DESCRIPTION: start recording impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::startRecording()
{
    int32_t rc = NO_ERROR;

    LOGI("E");

    m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);

    //link meta stream with video channel if low power mode.
    if (isLowPowerMode()) {
        // Find and try to link a metadata stream from preview channel
        QCameraChannel *pMetaChannel = NULL;
        QCameraStream *pMetaStream = NULL;
        QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];

        if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
            pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
            uint32_t streamNum = pMetaChannel->getNumOfStreams();
            QCameraStream *pStream = NULL;
            for (uint32_t i = 0 ; i < streamNum ; i++ ) {
                pStream = pMetaChannel->getStreamByIndex(i);
                if ((NULL != pStream) &&
                        (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
                    pMetaStream = pStream;
                    break;
                }
            }
        }

        if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
            rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
            if (NO_ERROR != rc) {
                LOGW("Metadata stream link failed %d", rc);
            }
        }
    }

    if (rc == NO_ERROR) {
        rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
    }

    if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
        QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
        if (!mParameters.is4k2kVideoResolution()) {
            // Find and try to link a metadata stream from preview channel
            QCameraChannel *pMetaChannel = NULL;
            QCameraStream *pMetaStream = NULL;

            if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
                pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
                uint32_t streamNum = pMetaChannel->getNumOfStreams();
                QCameraStream *pStream = NULL;
                for (uint32_t i = 0 ; i < streamNum ; i++ ) {
                    pStream = pMetaChannel->getStreamByIndex(i);
                    if ((NULL != pStream) &&
                            (CAM_STREAM_TYPE_METADATA ==
                            pStream->getMyType())) {
                        pMetaStream = pStream;
                        break;
                    }
                }
            }

            if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
                rc = pChannel->linkStream(pMetaChannel, pMetaStream);
                if (NO_ERROR != rc) {
                    LOGW("Metadata stream link failed %d", rc);
                }
            }
        }
        LOGH("START snapshot Channel for TNR processing");
        rc = pChannel->start();
    }

    m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);

    if (rc == NO_ERROR) {
        // Set power Hint for video encoding
        m_perfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0);
    }

    LOGI("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : stopRecording
 *
 * DESCRIPTION: stop recording impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::stopRecording()
{
    LOGI("E");

    // Disable power hint for video encoding
    m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE);

    m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);

    // stop snapshot channel
    if (mParameters.isTNRSnapshotEnabled()) {
        LOGH("STOP snapshot Channel for TNR processing");
        stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
    }
    int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);

    m_cbNotifier.flushVideoNotifications();

    m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_RECORDING);

    LOGI("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : releaseRecordingFrame
 *
 * DESCRIPTION: return video frame impl
 *
 * PARAMETERS :
 *   @opaque  : ptr to video frame to be returned
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
{
    int32_t rc = UNKNOWN_ERROR;
    QCameraVideoChannel *pChannel =
            (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
    LOGD("opaque data = %p",opaque);

    if(pChannel != NULL) {
        rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : autoFocus
 *
 * DESCRIPTION: start auto focus impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::autoFocus()
{
    int rc = NO_ERROR;
    cam_focus_mode_type focusMode = mParameters.getFocusMode();
    LOGH("E");

    switch (focusMode) {
    case CAM_FOCUS_MODE_AUTO:
    case CAM_FOCUS_MODE_MACRO:
    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
        mActiveAF = true;
        LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
                focusMode, m_currentFocusState);
        rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
        break;
    case CAM_FOCUS_MODE_INFINITY:
    case CAM_FOCUS_MODE_FIXED:
    case CAM_FOCUS_MODE_EDOF:
    default:
        LOGI("No ops in focusMode (%d)", focusMode);
        rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
        break;
    }

    if (NO_ERROR != rc) {
        mActiveAF = false;
    }
    LOGH("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : cancelAutoFocus
 *
 * DESCRIPTION: cancel auto focus impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::cancelAutoFocus()
{
    int rc = NO_ERROR;
    cam_focus_mode_type focusMode = mParameters.getFocusMode();

    switch (focusMode) {
    case CAM_FOCUS_MODE_AUTO:
    case CAM_FOCUS_MODE_MACRO:
    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
        mActiveAF = false;
        rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
        break;
    case CAM_FOCUS_MODE_INFINITY:
    case CAM_FOCUS_MODE_FIXED:
    case CAM_FOCUS_MODE_EDOF:
    default:
        LOGD("No ops in focusMode (%d)", focusMode);
        break;
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : processUFDumps
 *
 * DESCRIPTION: process UF jpeg dumps for refocus support
 *
 * PARAMETERS :
 *   @evt     : payload of jpeg event, including information about jpeg encoding
 *              status, jpeg size and so on.
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *
 * NOTE       : none
 *==========================================================================*/
bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
{
   bool ret = true;
   if (mParameters.isUbiRefocus()) {
       int index = (int)getOutputImageCount();
       bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
       char name[FILENAME_MAX];

       camera_memory_t *jpeg_mem = NULL;
       omx_jpeg_ouput_buf_t *jpeg_out = NULL;
       size_t dataLen;
       uint8_t *dataPtr;
       if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
           LOGE("Init PProc Deferred work failed");
           return false;
       }
       if (!m_postprocessor.getJpegMemOpt()) {
           dataLen = evt->out_data.buf_filled_len;
           dataPtr = evt->out_data.buf_vaddr;
       } else {
           jpeg_out  = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
           if (!jpeg_out) {
              LOGE("Null pointer detected");
              return false;
           }
           jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
           if (!jpeg_mem) {
              LOGE("Null pointer detected");
              return false;
           }
           dataPtr = (uint8_t *)jpeg_mem->data;
           dataLen = jpeg_mem->size;
       }

       if (allFocusImage)  {
           snprintf(name, sizeof(name), "AllFocusImage");
           index = -1;
       } else {
           snprintf(name, sizeof(name), "%d", 0);
       }
       CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
           dataPtr, dataLen);
       LOGD("Dump the image %d %d allFocusImage %d",
           getOutputImageCount(), index, allFocusImage);
       setOutputImageCount(getOutputImageCount() + 1);
       if (!allFocusImage) {
           ret = false;
       }
   }
   return ret;
}

/*===========================================================================
 * FUNCTION   : unconfigureAdvancedCapture
 *
 * DESCRIPTION: unconfigure Advanced Capture.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
{
    int32_t rc = NO_ERROR;

    /*Disable Quadra CFA mode*/
    LOGH("Disabling Quadra CFA mode");
    mParameters.setQuadraCfaMode(false, true);

    if (mAdvancedCaptureConfigured) {

        mAdvancedCaptureConfigured = false;

        if(mIs3ALocked) {
            mParameters.set3ALock(false);
            mIs3ALocked = false;
        }
        if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
            rc = mParameters.setToneMapMode(true, true);
            if (rc != NO_ERROR) {
                LOGW("Failed to enable tone map during HDR/AEBracketing");
            }
            mHDRBracketingEnabled = false;
            rc = mParameters.stopAEBracket();
        } else if ((mParameters.isChromaFlashEnabled())
                || (mFlashConfigured && !mLongshotEnabled)
                || (mLowLightConfigured == true)
                || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
            rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured);
        } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
            rc = configureAFBracketing(false);
        } else if (mParameters.isOptiZoomEnabled()) {
            rc = mParameters.setAndCommitZoom(mZoomLevel);
            setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
        } else if (mParameters.isStillMoreEnabled()) {
            cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
            stillmore_config.burst_count = 0;
            mParameters.setStillMoreSettings(stillmore_config);

            /* If SeeMore is running, it will handle re-enabling tone map */
            if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
                rc = mParameters.setToneMapMode(true, true);
                if (rc != NO_ERROR) {
                    LOGW("Failed to enable tone map during StillMore");
                }
            }

            /* Re-enable Tintless */
            mParameters.setTintless(true);
        } else {
            LOGW("No Advanced Capture feature enabled!!");
            rc = BAD_VALUE;
        }
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : configureAdvancedCapture
 *
 * DESCRIPTION: configure Advanced Capture.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::configureAdvancedCapture()
{
    LOGH("E");
    int32_t rc = NO_ERROR;

    rc = mParameters.checkFeatureConcurrency();
    if (rc != NO_ERROR) {
        LOGE("Cannot support Advanced capture modes");
        return rc;
    }
    /*Enable Quadra CFA mode*/
    LOGH("Enabling Quadra CFA mode");
    mParameters.setQuadraCfaMode(true, true);

    setOutputImageCount(0);
    mInputCount = 0;
    mAdvancedCaptureConfigured = true;
    /* Display should be disabled for advanced modes */
    bool bSkipDisplay = true;

    if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
        // no Advance capture settings for Aux camera
        LOGH("X Secondary Camera, no need to process!! ");
        return rc;
    }

    /* Do not stop display if in stillmore livesnapshot */
    if (mParameters.isStillMoreEnabled() &&
            mParameters.isSeeMoreEnabled()) {
        bSkipDisplay = false;
    }
    if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
        rc = configureAFBracketing();
    } else if (mParameters.isOptiZoomEnabled()) {
        rc = configureOptiZoom();
    } else if(mParameters.isHDREnabled()) {
        rc = configureHDRBracketing();
        if (mHDRBracketingEnabled) {
            rc = mParameters.setToneMapMode(false, true);
            if (rc != NO_ERROR) {
                LOGW("Failed to disable tone map during HDR");
            }
        }
    } else if (mParameters.isAEBracketEnabled()) {
        rc = mParameters.setToneMapMode(false, true);
        if (rc != NO_ERROR) {
            LOGW("Failed to disable tone map during AEBracketing");
        }
        rc = configureAEBracketing();
    } else if (mParameters.isStillMoreEnabled()) {
        bSkipDisplay = false;
        rc = configureStillMore();
    } else if ((mParameters.isChromaFlashEnabled())
            || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
            || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
        rc = mParameters.configFrameCapture(TRUE);
        if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) {
            mLowLightConfigured = true;
        }
    } else if (mFlashNeeded && !mLongshotEnabled) {
        rc = mParameters.configFrameCapture(TRUE);
        mFlashConfigured = true;
        bSkipDisplay = false;
    } else {
        LOGH("Advanced Capture feature not enabled!! ");
        mAdvancedCaptureConfigured = false;
        bSkipDisplay = false;
    }

    if (m_postprocessor.isHalPPEnabled()) {
        LOGH("HALPP is enabled, check if halpp is needed for current snapshot.");
        configureHalPostProcess();
    }

    LOGH("Stop preview temporarily for advanced captures");
    setDisplaySkip(bSkipDisplay);

    LOGH("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : configureAFBracketing
 *
 * DESCRIPTION: configure AF Bracketing.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
{
    LOGH("E");
    int32_t rc = NO_ERROR;
    cam_af_bracketing_t *af_bracketing_need;

    if (mParameters.isUbiRefocus()) {
        af_bracketing_need =
                &gCamCapability[mCameraId]->refocus_af_bracketing_need;
    } else {
        af_bracketing_need =
                &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
    }

    //Enable AF Bracketing.
    cam_af_bracketing_t afBracket;
    memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
    afBracket.enable = enable;
    afBracket.burst_count = af_bracketing_need->burst_count;

    for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
        afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
        LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
    }
    //Send cmd to backend to set AF Bracketing for Ubi Focus.
    rc = mParameters.commitAFBracket(afBracket);
    if ( NO_ERROR != rc ) {
        LOGE("cannot configure AF bracketing");
        return rc;
    }
    if (enable) {
        mParameters.set3ALock(true);
        mIs3ALocked = true;
    }
    LOGH("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : configureHDRBracketing
 *
 * DESCRIPTION: configure HDR Bracketing.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::configureHDRBracketing()
{
    LOGH("E");
    int32_t rc = NO_ERROR;

    cam_hdr_bracketing_info_t& hdrBracketingSetting =
            gCamCapability[mCameraId]->hdr_bracketing_setting;

    // 'values' should be in "idx1,idx2,idx3,..." format
    uint32_t hdrFrameCount =
            hdrBracketingSetting.num_frames;
    LOGH("HDR values %d, %d frame count: %u",
          (int8_t) hdrBracketingSetting.exp_val.values[0],
          (int8_t) hdrBracketingSetting.exp_val.values[1],
          hdrFrameCount);

    // Enable AE Bracketing for HDR
    cam_exp_bracketing_t aeBracket;
    memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
    aeBracket.mode =
        hdrBracketingSetting.exp_val.mode;

    if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
        mHDRBracketingEnabled = true;
    }

    String8 tmp;
    for (uint32_t i = 0; i < hdrFrameCount; i++) {
        tmp.appendFormat("%d",
            (int8_t) hdrBracketingSetting.exp_val.values[i]);
        tmp.append(",");
    }
    if (mParameters.isHDR1xFrameEnabled()
        && mParameters.isHDR1xExtraBufferNeeded()) {
            tmp.appendFormat("%d", 0);
            tmp.append(",");
    }

    if( !tmp.isEmpty() &&
        ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
        //Trim last comma
        memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
        memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
    }

    LOGH("HDR config values %s",
          aeBracket.values);
    rc = mParameters.setHDRAEBracket(aeBracket);
    if ( NO_ERROR != rc ) {
        LOGE("cannot configure HDR bracketing");
        return rc;
    }
    LOGH("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : configureAEBracketing
 *
 * DESCRIPTION: configure AE Bracketing.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::configureAEBracketing()
{
    LOGH("E");
    int32_t rc = NO_ERROR;

    rc = mParameters.setAEBracketing();
    if ( NO_ERROR != rc ) {
        LOGE("cannot configure AE bracketing");
        return rc;
    }
    LOGH("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : configureOptiZoom
 *
 * DESCRIPTION: configure Opti Zoom.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::configureOptiZoom()
{
    int32_t rc = NO_ERROR;

    //store current zoom level.
    mZoomLevel = mParameters.getParmZoomLevel();

    //set zoom level to 1x;
    mParameters.setAndCommitZoom(0);

    mParameters.set3ALock(true);
    mIs3ALocked = true;

    return rc;
}

/*===========================================================================
 * FUNCTION   : configureStillMore
 *
 * DESCRIPTION: configure StillMore.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::configureStillMore()
{
    int32_t rc = NO_ERROR;
    uint8_t burst_cnt = 0;
    cam_still_more_t stillmore_config;
    cam_still_more_t stillmore_cap;

    /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
    if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
        rc = mParameters.setToneMapMode(false, true);
        if (rc != NO_ERROR) {
            LOGW("Failed to disable tone map during StillMore");
        }
    }

    /* Lock 3A */
    mParameters.set3ALock(true);
    mIs3ALocked = true;

    /* Disable Tintless */
    mParameters.setTintless(false);

    /* Initialize burst count from capability */
    stillmore_cap = mParameters.getStillMoreCapability();
    burst_cnt = stillmore_cap.max_burst_count;

    /* Reconfigure burst count from dynamic scene data */
    cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
    if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
            dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
        burst_cnt = dynamic_img_data.input_count;
    }

    /* Reconfigure burst count in the case of liveshot */
    if (mParameters.isSeeMoreEnabled()) {
        burst_cnt = 1;
    }

    /* Reconfigure burst count from user input */
    char prop[PROPERTY_VALUE_MAX];
    property_get("persist.camera.imglib.stillmore", prop, "0");
    uint8_t burst_setprop = (uint32_t)atoi(prop);
    if (burst_setprop != 0)  {
       if ((burst_setprop < stillmore_cap.min_burst_count) ||
               (burst_setprop > stillmore_cap.max_burst_count)) {
           burst_cnt = stillmore_cap.max_burst_count;
       } else {
           burst_cnt = burst_setprop;
       }
    }

    memset(&stillmore_config, 0, sizeof(cam_still_more_t));
    stillmore_config.burst_count = burst_cnt;
    mParameters.setStillMoreSettings(stillmore_config);

    LOGH("Stillmore burst %d", burst_cnt);

    return rc;
}

/*===========================================================================
 * FUNCTION   : configureHalPostProcess
 *
 * DESCRIPTION: config hal postproc (HALPP) for current snapshot.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::configureHalPostProcess()
{
    LOGD("E");
    int32_t rc = NO_ERROR;

    if (!m_postprocessor.isHalPPEnabled()) {
        m_bNeedHalPP = FALSE;
        return rc;
    }

    /* check if halpp is needed in dual camera mode */
    if (isDualCamera()) {
        if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot == TRUE) {
            LOGH("Use HALPP for dual camera bundle snapshot.");
            m_bNeedHalPP = TRUE;
        }
        return rc;
    }

    return rc;
    LOGD("X");
}


/*===========================================================================
 * FUNCTION   : stopAdvancedCapture
 *
 * DESCRIPTION: stops advanced capture based on capture type
 *
 * PARAMETERS :
 *   @pChannel : channel.
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::stopAdvancedCapture(
        QCameraPicChannel *pChannel)
{
    LOGH("stop bracketig");
    int32_t rc = NO_ERROR;

    if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
        rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
    } else if (mParameters.isChromaFlashEnabled()
            || (mFlashConfigured && !mLongshotEnabled)
            || (mLowLightConfigured == true)
            || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
        rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
        mFlashConfigured = false;
        mLowLightConfigured = false;
    } else if(mParameters.isHDREnabled()
            || mParameters.isAEBracketEnabled()) {
        rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
    } else if (mParameters.isOptiZoomEnabled()) {
        rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
    } else if (mParameters.isStillMoreEnabled()) {
        LOGH("stopAdvancedCapture not needed for StillMore");
    } else {
        LOGH("No Advanced Capture feature enabled!");
        rc = BAD_VALUE;
    }

    m_bNeedHalPP = FALSE;
    return rc;
}

/*===========================================================================
 * FUNCTION   : startAdvancedCapture
 *
 * DESCRIPTION: starts advanced capture based on capture type
 *
 * PARAMETERS :
 *   @pChannel : channel.
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::startAdvancedCapture(
        QCameraPicChannel *pChannel)
{
    LOGH("Start bracketing");
    int32_t rc = NO_ERROR;

    if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
        rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
    } else if (mParameters.isOptiZoomEnabled()) {
        rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
    } else if (mParameters.isStillMoreEnabled()) {
        LOGH("startAdvancedCapture not needed for StillMore");
    } else if (mParameters.isHDREnabled()
            || mParameters.isAEBracketEnabled()) {
        rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
    } else if (mParameters.isChromaFlashEnabled()
            || (mFlashNeeded && !mLongshotEnabled)
            || (mLowLightConfigured == true)
            || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
        cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
        rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
    } else {
        LOGE("No Advanced Capture feature enabled!");
        rc = BAD_VALUE;
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : preTakePicture
 *
 * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::preTakePicture()
{
    int32_t rc = NO_ERROR;
    LOGH("E");
    if (mParameters.getRecordingHintValue() == true) {

        // Give HWI control to restart preview only in single camera mode.
        // In dual-cam mode, this control belongs to muxer.
        if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
            LOGH("restart preview if rec hint is true and preview is running");
            stopPreview();
            mParameters.updateRecordingHintValue(FALSE);
            // start preview again
            rc = preparePreview();
            if (rc == NO_ERROR) {
                rc = startPreview();
                if (rc != NO_ERROR) {
                    unpreparePreview();
                }
            }
        }
        else
        {
            // For dual cam mode, update the flag mPreviewRestartNeeded to true
            // Restart control will be handled by muxer.
            mPreviewRestartNeeded = true;
        }
    }

    LOGH("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : takePicture
 *
 * DESCRIPTION: take picture impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::takePicture()
{
    int rc = NO_ERROR;

    // Get total number for snapshots (retro + regular)
    uint8_t numSnapshots = mParameters.getNumOfSnapshots();
    // Get number of retro-active snapshots
    uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
    LOGH("E");

    //Set rotation value from user settings as Jpeg rotation
    //to configure back-end modules.
    mParameters.setJpegRotation(mParameters.getRotation());

    // Check if retro-active snapshots are not enabled
    if (!isRetroPicture() || !mParameters.isZSLMode()) {
      numRetroSnapshots = 0;
      LOGH("Reset retro snaphot count to zero");
    }

    //Do special configure for advanced capture modes.
    rc = configureAdvancedCapture();
    if (rc != NO_ERROR) {
        LOGE("Unsupported capture call");
        return rc;
    }

    if (mAdvancedCaptureConfigured) {
        numSnapshots = mParameters.getBurstCountForAdvancedCapture();
    }

    if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot) {
        char prop[PROPERTY_VALUE_MAX];
        memset(prop, 0, sizeof(prop));
        property_get("persist.camera.dualfov.jpegnum", prop, "1");
        int dualfov_snap_num = atoi(prop);

        memset(prop, 0, sizeof(prop));
        property_get("persist.camera.halpp", prop, "0");
        int halpp_enabled = atoi(prop);
        if(halpp_enabled == 0) {
            dualfov_snap_num = MM_CAMERA_MAX_CAM_CNT;
        }

        dualfov_snap_num = (dualfov_snap_num == 0) ? 1 : dualfov_snap_num;
        LOGD("dualfov_snap_num:%d", dualfov_snap_num);
        numSnapshots /= dualfov_snap_num;
    }

    LOGI("snap count = %d zsl = %d advanced = %d, active camera:%d",
            numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured, mActiveCameras);

    if (mParameters.isZSLMode()) {
        QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
        QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
        if (NULL != pPicChannel) {

            if (mParameters.getofflineRAW()) {
                startRAWChannel(pPicChannel);
                pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
                if (pPicChannel == NULL) {
                    LOGE("RAW Channel is NULL in Manual capture mode");
                    stopRAWChannel();
                    return UNKNOWN_ERROR;
                }
            }

            rc = configureOnlineRotation(*pPicChannel);
            if (rc != NO_ERROR) {
                LOGE("online rotation failed");
                return rc;
            }

            // start postprocessor
            DeferWorkArgs args;
            memset(&args, 0, sizeof(DeferWorkArgs));

            args.pprocArgs = pPicChannel;

            // No need to wait for mInitPProcJob here, because it was
            // queued in startPreview, and will definitely be processed before
            // mReprocJob can begin.
            mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
                    args);
            if (mReprocJob == 0) {
                LOGE("Failure: Unable to start pproc");
                return -ENOMEM;
            }

            // Check if all preview buffers are mapped before creating
            // a jpeg session as preview stream buffers are queried during the same
            uint8_t numStreams = pChannel->getNumOfStreams();
            QCameraStream *pStream = NULL;
            QCameraStream *pPreviewStream = NULL;
            for (uint8_t i = 0 ; i < numStreams ; i++ ) {
                pStream = pChannel->getStreamByIndex(i);
                if (!pStream)
                    continue;
                if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
                    pPreviewStream = pStream;
                    break;
                }
            }
            if (pPreviewStream != NULL) {
                Mutex::Autolock l(mMapLock);
                QCameraMemory *pMemory = pStream->getStreamBufs();
                if (!pMemory) {
                    LOGE("Error!! pMemory is NULL");
                    return -ENOMEM;
                }

                uint8_t waitCnt = 2;
                while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
                    LOGL(" Waiting for preview buffers to be mapped");
                    mMapCond.waitRelative(
                            mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
                    LOGL("Wait completed!!");
                    waitCnt--;
                }
                // If all buffers are not mapped after retries, assert
                assert(pMemory->checkIfAllBuffersMapped());
            } else {
                assert(pPreviewStream);
            }

            // Create JPEG session
            mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
                    args);
            if (mJpegJob == 0) {
                LOGE("Failed to queue CREATE_JPEG_SESSION");
                if (NO_ERROR != waitDeferredWork(mReprocJob)) {
                        LOGE("Reprocess Deferred work was failed");
                }
                m_postprocessor.stop();
                return -ENOMEM;
            }

            if (mAdvancedCaptureConfigured) {
                rc = startAdvancedCapture(pPicChannel);
                if (rc != NO_ERROR) {
                    LOGE("cannot start zsl advanced capture");
                    return rc;
                }
            }
            if (mLongshotEnabled && mPrepSnapRun) {
                mCameraHandle->ops->start_zsl_snapshot(
                        mCameraHandle->camera_handle,
                        pPicChannel->getMyHandle());
            }
            // If frame sync is ON and it is a SECONDARY camera,
            // we do not need to send the take picture command to interface
            // It will be handled along with PRIMARY camera takePicture request
            mm_camera_req_buf_t buf;
            memset(&buf, 0x0, sizeof(buf));
            if ((!mParameters.isAdvCamFeaturesEnabled() &&
                    !mFlashNeeded &&
                    !isLongshotEnabled() &&
                    isFrameSyncEnabled()) &&
                    (getRelatedCamSyncInfo()->sync_control ==
                    CAM_SYNC_RELATED_SENSORS_ON)) {
                if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
                    buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
                    buf.num_buf_requested = numSnapshots;
                    rc = pPicChannel->takePicture(&buf);
                    if (rc != NO_ERROR) {
                        LOGE("FS_DBG cannot take ZSL picture, stop pproc");
                        if (NO_ERROR != waitDeferredWork(mReprocJob)) {
                            LOGE("Reprocess Deferred work failed");
                            return UNKNOWN_ERROR;
                        }
                        if (NO_ERROR != waitDeferredWork(mJpegJob)) {
                            LOGE("Jpeg Deferred work failed");
                            return UNKNOWN_ERROR;
                        }
                        m_postprocessor.stop();
                        return rc;
                    }
                    LOGI("PRIMARY camera: send frame sync takePicture!!");
                }
            } else {
                buf.type = MM_CAMERA_REQ_SUPER_BUF;
                buf.num_buf_requested = numSnapshots;
                buf.num_retro_buf_requested = numRetroSnapshots;
                rc = pPicChannel->takePicture(&buf);
                if (rc != NO_ERROR) {
                    LOGE("cannot take ZSL picture, stop pproc");
                        if (NO_ERROR != waitDeferredWork(mReprocJob)) {
                            LOGE("Reprocess Deferred work failed");
                            return UNKNOWN_ERROR;
                        }
                        if (NO_ERROR != waitDeferredWork(mJpegJob)) {
                            LOGE("Jpeg Deferred work failed");
                            return UNKNOWN_ERROR;
                        }
                    m_postprocessor.stop();
                    return rc;
                }
            }
        } else {
            LOGE("ZSL channel is NULL");
            return UNKNOWN_ERROR;
        }
    } else {

        // start snapshot
        if (mParameters.isJpegPictureFormat() ||
                mParameters.isNV16PictureFormat() ||
                mParameters.isNV21PictureFormat()) {

            //STOP Preview for Non ZSL use case
            stopPreview();

            //Config CAPTURE channels
            rc = declareSnapshotStreams();
            if (NO_ERROR != rc) {
                return rc;
            }

            rc = addCaptureChannel();
            if ((rc == NO_ERROR) &&
                    (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {

                if (!mParameters.getofflineRAW()) {
                    rc = configureOnlineRotation(
                        *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
                    if (rc != NO_ERROR) {
                        LOGE("online rotation failed");
                        delChannel(QCAMERA_CH_TYPE_CAPTURE);
                        return rc;
                    }
                }

                DeferWorkArgs args;
                memset(&args, 0, sizeof(DeferWorkArgs));

                args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];

                // No need to wait for mInitPProcJob here, because it was
                // queued in startPreview, and will definitely be processed before
                // mReprocJob can begin.
                mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
                        args);
                if (mReprocJob == 0) {
                    LOGE("Failure: Unable to start pproc");
                    return -ENOMEM;
                }

                // Create JPEG session
                mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
                        args);
                if (mJpegJob == 0) {
                    LOGE("Failed to queue CREATE_JPEG_SESSION");
                    if (NO_ERROR != waitDeferredWork(mReprocJob)) {
                        LOGE("Reprocess Deferred work was failed");
                    }
                    m_postprocessor.stop();
                    return -ENOMEM;
                }

                // start catpure channel
                rc =  m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
                if (rc != NO_ERROR) {
                    LOGE("cannot start capture channel");
                    if (NO_ERROR != waitDeferredWork(mReprocJob)) {
                        LOGE("Reprocess Deferred work failed");
                        return UNKNOWN_ERROR;
                    }
                    if (NO_ERROR != waitDeferredWork(mJpegJob)) {
                        LOGE("Jpeg Deferred work failed");
                        return UNKNOWN_ERROR;
                    }
                    delChannel(QCAMERA_CH_TYPE_CAPTURE);
                    return rc;
                }

                QCameraPicChannel *pCapChannel =
                    (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
                if (NULL != pCapChannel) {
                    if (mParameters.isUbiFocusEnabled() ||
                            mParameters.isUbiRefocus() ||
                            mParameters.isChromaFlashEnabled()) {
                        rc = startAdvancedCapture(pCapChannel);
                        if (rc != NO_ERROR) {
                            LOGE("cannot start advanced capture");
                            return rc;
                        }
                    }
                }
                if ( mLongshotEnabled ) {
                    rc = longShot();
                    if (NO_ERROR != rc) {
                        if (NO_ERROR != waitDeferredWork(mReprocJob)) {
                            LOGE("Reprocess Deferred work failed");
                            return UNKNOWN_ERROR;
                        }
                        if (NO_ERROR != waitDeferredWork(mJpegJob)) {
                            LOGE("Jpeg Deferred work failed");
                            return UNKNOWN_ERROR;
                        }
                        delChannel(QCAMERA_CH_TYPE_CAPTURE);
                        return rc;
                    }
                }
            } else {
                LOGE("cannot add capture channel");
                delChannel(QCAMERA_CH_TYPE_CAPTURE);
                return rc;
            }
        } else {
            // Stop Preview before taking NZSL snapshot
            stopPreview();

            rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
            if (NO_ERROR != rc) {
                LOGE("Raw dimension update failed %d", rc);
                return rc;
            }

            rc = declareSnapshotStreams();
            if (NO_ERROR != rc) {
                LOGE("RAW stream info configuration failed %d", rc);
                return rc;
            }

            rc = addChannel(QCAMERA_CH_TYPE_RAW);
            if (rc == NO_ERROR) {
                // start postprocessor
                if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
                    LOGE("Reprocess Deferred work failed");
                    return UNKNOWN_ERROR;
                }

                rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
                if (rc != NO_ERROR) {
                    LOGE("cannot start postprocessor");
                    delChannel(QCAMERA_CH_TYPE_RAW);
                    return rc;
                }

                rc = startChannel(QCAMERA_CH_TYPE_RAW);
                if (rc != NO_ERROR) {
                    LOGE("cannot start raw channel");
                    m_postprocessor.stop();
                    delChannel(QCAMERA_CH_TYPE_RAW);
                    return rc;
                }
            } else {
                LOGE("cannot add raw channel");
                return rc;
            }
        }
    }

    //When take picture, stop sending preview callbacks to APP
    m_stateMachine.setPreviewCallbackNeeded(false);
    LOGI("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : configureOnlineRotation
 *
 * DESCRIPTION: Configure backend with expected rotation for snapshot stream
 *
 * PARAMETERS :
 *    @ch     : Channel containing a snapshot stream
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
{
    int rc = NO_ERROR;
    uint32_t streamId = 0;
    QCameraStream *pStream = NULL;

    for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
        QCameraStream *stream = ch.getStreamByIndex(i);
        if ((NULL != stream) &&
                ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
                || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
            pStream = stream;
            break;
        }
    }

    if (NULL == pStream) {
        LOGE("No snapshot stream found!");
        return BAD_VALUE;
    }

    streamId = pStream->getMyServerID();
    // Update online rotation configuration
    rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
            mParameters.getDeviceRotation());
    if (rc != NO_ERROR) {
        LOGE("addOnlineRotation failed %d", rc);
        return rc;
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : declareSnapshotStreams
 *
 * DESCRIPTION: Configure backend with expected snapshot streams
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::declareSnapshotStreams()
{
    int rc = NO_ERROR;

    // Update stream info configuration
    rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
    if (rc != NO_ERROR) {
        LOGE("setStreamConfigure failed %d", rc);
        return rc;
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : longShot
 *
 * DESCRIPTION: Queue one more ZSL frame
 *              in the longshot pipe.
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::longShot()
{
    int32_t rc = NO_ERROR;
    uint8_t numSnapshots = mParameters.getNumOfSnapshots();
    QCameraPicChannel *pChannel = NULL;

    if (mParameters.isZSLMode()) {
        pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
    } else {
        pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
    }

    if (NULL != pChannel) {
        mm_camera_req_buf_t buf;
        memset(&buf, 0x0, sizeof(buf));
        buf.type = MM_CAMERA_REQ_SUPER_BUF;
        buf.num_buf_requested = numSnapshots;
        rc = pChannel->takePicture(&buf);
    } else {
        LOGE("Capture channel not initialized!");
        rc = NO_INIT;
        goto end;
    }

end:
    return rc;
}

/*===========================================================================
 * FUNCTION   : stopCaptureChannel
 *
 * DESCRIPTION: Stops capture channel
 *
 * PARAMETERS :
 *   @destroy : Set to true to stop and delete camera channel.
 *              Set to false to only stop capture channel.
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
{
    int rc = NO_ERROR;
    if (mParameters.isJpegPictureFormat() ||
        mParameters.isNV16PictureFormat() ||
        mParameters.isNV21PictureFormat()) {
        mParameters.setQuadraCfaMode(false, true);
        rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
        if (destroy && (NO_ERROR == rc)) {
            // Destroy camera channel but dont release context
            waitDeferredWork(mJpegJob);
            rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
        }
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : cancelPicture
 *
 * DESCRIPTION: cancel picture impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::cancelPicture()
{
    waitDeferredWork(mReprocJob);
    waitDeferredWork(mJpegJob);

    //stop post processor
    m_postprocessor.stop();

    unconfigureAdvancedCapture();
    LOGH("Enable display frames again");
    setDisplaySkip(FALSE);

    if (mParameters.isZSLMode()) {
        QCameraPicChannel *pPicChannel = NULL;
        if (mParameters.getofflineRAW()) {
            pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
        } else {
            pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
        }
        if (NULL != pPicChannel) {
            pPicChannel->cancelPicture();
            stopRAWChannel();
            stopAdvancedCapture(pPicChannel);
        }
    } else {

        // normal capture case
        if (mParameters.isJpegPictureFormat() ||
            mParameters.isNV16PictureFormat() ||
            mParameters.isNV21PictureFormat()) {
            stopChannel(QCAMERA_CH_TYPE_CAPTURE);
            delChannel(QCAMERA_CH_TYPE_CAPTURE);
        } else {
            stopChannel(QCAMERA_CH_TYPE_RAW);
            delChannel(QCAMERA_CH_TYPE_RAW);
        }
    }

    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : captureDone
 *
 * DESCRIPTION: Function called when the capture is completed before encoding
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::captureDone()
{
    qcamera_sm_internal_evt_payload_t *payload =
       (qcamera_sm_internal_evt_payload_t *)
       malloc(sizeof(qcamera_sm_internal_evt_payload_t));
    if (NULL != payload) {
        memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
        payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
        int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
        if (rc != NO_ERROR) {
            LOGE("processEvt ZSL capture done failed");
            free(payload);
            payload = NULL;
        }
    } else {
        LOGE("No memory for ZSL capture done event");
    }
}

/*===========================================================================
 * FUNCTION   : Live_Snapshot_thread
 *
 * DESCRIPTION: Seperate thread for taking live snapshot during recording
 *
 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
 *
 * RETURN     : none
 *==========================================================================*/
void* Live_Snapshot_thread (void* data)
{

    QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
    if (!hw) {
        LOGE("take_picture_thread: NULL camera device");
        return (void *)BAD_VALUE;
    }
    if (hw->bLiveSnapshot) {
        hw->takeLiveSnapshot_internal();
    } else {
        hw->cancelLiveSnapshot_internal();
    }
    return (void* )NULL;
}

/*===========================================================================
 * FUNCTION   : Int_Pic_thread
 *
 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
 *
 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
 *
 * RETURN     : none
 *==========================================================================*/
void* Int_Pic_thread (void* data)
{
    int rc = NO_ERROR;

    QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);

    if (!hw) {
        LOGE("take_picture_thread: NULL camera device");
        return (void *)BAD_VALUE;
    }

    bool JpegMemOpt = false;
    char raw_format[PROPERTY_VALUE_MAX];

    memset(raw_format, 0, sizeof(raw_format));

    rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
    if (rc == NO_ERROR) {
        hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
    } else {
        //Snapshot attempt not successful, we need to do cleanup here
        hw->clearIntPendingEvents();
    }

    return (void* )NULL;
}

/*===========================================================================
 * FUNCTION   : takeLiveSnapshot
 *
 * DESCRIPTION: take live snapshot during recording
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::takeLiveSnapshot()
{
    int rc = NO_ERROR;
    if (mLiveSnapshotThread != 0) {
        pthread_join(mLiveSnapshotThread,NULL);
        mLiveSnapshotThread = 0;
    }
    bLiveSnapshot = true;
    rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
    if (!rc) {
        pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : takePictureInternal
 *
 * DESCRIPTION: take snapshot triggered by backend
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::takePictureInternal()
{
    int rc = NO_ERROR;
    rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
    if (!rc) {
        pthread_setname_np(mIntPicThread, "CAM_IntPic");
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : checkIntPicPending
 *
 * DESCRIPTION: timed wait for jpeg completion event, and send
 *                        back completion event to backend
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
{
    bool bSendToBackend = true;
    cam_int_evt_params_t params;
    int rc = NO_ERROR;

    struct timespec   ts;
    struct timeval    tp;
    gettimeofday(&tp, NULL);
    ts.tv_sec  = tp.tv_sec + 5;
    ts.tv_nsec = tp.tv_usec * 1000;

    if (true == m_bIntJpegEvtPending ||
        (true == m_bIntRawEvtPending)) {
        //Waiting in HAL for snapshot taken notification
        pthread_mutex_lock(&m_int_lock);
        rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
        if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
            //Hit a timeout, or some spurious activity
            bSendToBackend = false;
        }

        if (true == m_bIntJpegEvtPending) {
            params.event_type = 0;
            mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
        } else if (true == m_bIntRawEvtPending) {
            params.event_type = 1;
            mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
        }
        pthread_mutex_unlock(&m_int_lock);

        if (true == m_bIntJpegEvtPending) {
            //Attempting to restart preview after taking JPEG snapshot
            lockAPI();
            rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
            unlockAPI();
            m_postprocessor.setJpegMemOpt(JpegMemOpt);
        } else if (true == m_bIntRawEvtPending) {
            //Attempting to restart preview after taking RAW snapshot
            stopChannel(QCAMERA_CH_TYPE_RAW);
            delChannel(QCAMERA_CH_TYPE_RAW);
            //restoring the old raw format
            property_set("persist.camera.raw.format", raw_format);
        }

        if (true == bSendToBackend) {
            //send event back to server with the file path
            params.dim = m_postprocessor.m_dst_dim;
            memcpy(&params.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
            memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
            params.size = mBackendFileSize;
            rc = mParameters.setIntEvent(params);
        }

        clearIntPendingEvents();
    }

    return;
}

/*===========================================================================
 * FUNCTION   : takeBackendPic_internal
 *
 * DESCRIPTION: take snapshot triggered by backend
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
{
    int rc = NO_ERROR;
    qcamera_api_result_t apiResult;

    lockAPI();
    //Set rotation value from user settings as Jpeg rotation
    //to configure back-end modules.
    mParameters.setJpegRotation(mParameters.getRotation());

    setRetroPicture(0);
    /* Prepare snapshot in case LED needs to be flashed */
    if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
        // Start Preparing for normal Frames
        LOGH("Start Prepare Snapshot");
        /* Prepare snapshot in case LED needs to be flashed */
        rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
        if (rc == NO_ERROR) {
            waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
            rc = apiResult.status;
        }
        LOGH("Prep Snapshot done rc = %d", rc);
        mPrepSnapRun = true;
    }
    unlockAPI();

    if (true == m_bIntJpegEvtPending) {
        //Attempting to take JPEG snapshot
        if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
            LOGE("Init PProc Deferred work failed");
            return UNKNOWN_ERROR;
        }
        *JpegMemOpt = m_postprocessor.getJpegMemOpt();
        m_postprocessor.setJpegMemOpt(false);

        /* capture */
        lockAPI();
        LOGH("Capturing internal snapshot");
        rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
        if (rc == NO_ERROR) {
            waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
            rc = apiResult.status;
        }
        unlockAPI();
    } else if (true == m_bIntRawEvtPending) {
        //Attempting to take RAW snapshot
        (void)JpegMemOpt;
        stopPreview();

        //getting the existing raw format type
        property_get("persist.camera.raw.format", raw_format, "17");
        //setting it to a default know value for this task
        property_set("persist.camera.raw.format", "18");

        rc = addChannel(QCAMERA_CH_TYPE_RAW);
        if (rc == NO_ERROR) {
            // start postprocessor
            if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
                LOGE("Init PProc Deferred work failed");
                return UNKNOWN_ERROR;
            }
            rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
            if (rc != NO_ERROR) {
                LOGE("cannot start postprocessor");
                delChannel(QCAMERA_CH_TYPE_RAW);
                return rc;
            }

            rc = startChannel(QCAMERA_CH_TYPE_RAW);
            if (rc != NO_ERROR) {
                LOGE("cannot start raw channel");
                m_postprocessor.stop();
                delChannel(QCAMERA_CH_TYPE_RAW);
                return rc;
            }
        } else {
            LOGE("cannot add raw channel");
            return rc;
        }
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : clearIntPendingEvents
 *
 * DESCRIPTION: clear internal pending events pertaining to backend
 *                        snapshot requests
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
void QCamera2HardwareInterface::clearIntPendingEvents()
{
    int rc = NO_ERROR;

    if (true == m_bIntRawEvtPending) {
        preparePreview();
        startPreview();
    }
    if (true == m_bIntJpegEvtPending) {
        if (false == mParameters.isZSLMode()) {
            lockAPI();
            rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
            unlockAPI();
        }
    }

    pthread_mutex_lock(&m_int_lock);
    if (true == m_bIntJpegEvtPending) {
        m_bIntJpegEvtPending = false;
    } else if (true == m_bIntRawEvtPending) {
        m_bIntRawEvtPending = false;
    }
    pthread_mutex_unlock(&m_int_lock);
    return;
}

/*===========================================================================
 * FUNCTION   : takeLiveSnapshot_internal
 *
 * DESCRIPTION: take live snapshot during recording
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::takeLiveSnapshot_internal()
{
    int rc = NO_ERROR;

    QCameraChannel *pChannel = NULL;
    QCameraChannel *pPreviewChannel = NULL;
    QCameraStream  *pPreviewStream = NULL;
    QCameraStream  *pStream = NULL;

    //Set rotation value from user settings as Jpeg rotation
    //to configure back-end modules.
    mParameters.setJpegRotation(mParameters.getRotation());

    // Configure advanced capture
    rc = configureAdvancedCapture();
    if (rc != NO_ERROR) {
        LOGE("Unsupported capture call");
        goto end;
    }

    if (isLowPowerMode()) {
        pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
    } else {
        pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
    }

    if (NULL == pChannel) {
        LOGE("Snapshot/Video channel not initialized");
        rc = NO_INIT;
        goto end;
    }

    // Check if all preview buffers are mapped before creating
    // a jpeg session as preview stream buffers are queried during the same
    pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
    if (pPreviewChannel != NULL) {
        uint32_t numStreams = pPreviewChannel->getNumOfStreams();

        for (uint8_t i = 0 ; i < numStreams ; i++ ) {
            pStream = pPreviewChannel->getStreamByIndex(i);
            if (!pStream)
                continue;
            if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
                pPreviewStream = pStream;
                break;
            }
        }

        if (pPreviewStream != NULL) {
            Mutex::Autolock l(mMapLock);
            QCameraMemory *pMemory = pStream->getStreamBufs();
            if (!pMemory) {
                LOGE("Error!! pMemory is NULL");
                return -ENOMEM;
            }

            uint8_t waitCnt = 2;
            while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
                LOGL(" Waiting for preview buffers to be mapped");
                mMapCond.waitRelative(
                        mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
                LOGL("Wait completed!!");
                waitCnt--;
            }
            // If all buffers are not mapped after retries, assert
            assert(pMemory->checkIfAllBuffersMapped());
        } else {
            assert(pPreviewStream);
        }
    }

    DeferWorkArgs args;
    memset(&args, 0, sizeof(DeferWorkArgs));

    args.pprocArgs = pChannel;

    // No need to wait for mInitPProcJob here, because it was
    // queued in startPreview, and will definitely be processed before
    // mReprocJob can begin.
    mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
            args);
    if (mReprocJob == 0) {
        LOGE("Failed to queue CMD_DEF_PPROC_START");
        rc = -ENOMEM;
        goto end;
    }

    // Create JPEG session
    mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
            args);
    if (mJpegJob == 0) {
        LOGE("Failed to queue CREATE_JPEG_SESSION");
        if (NO_ERROR != waitDeferredWork(mReprocJob)) {
            LOGE("Reprocess Deferred work was failed");
        }
        m_postprocessor.stop();
        rc = -ENOMEM;
        goto end;
    }

    if (isLowPowerMode()) {
        mm_camera_req_buf_t buf;
        memset(&buf, 0x0, sizeof(buf));
        buf.type = MM_CAMERA_REQ_SUPER_BUF;
        buf.num_buf_requested = 1;
        rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
        goto end;
    }

    //Disable reprocess for 4K liveshot case
    if (!mParameters.is4k2kVideoResolution()) {
        rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
        if (rc != NO_ERROR) {
            LOGE("online rotation failed");
            if (NO_ERROR != waitDeferredWork(mReprocJob)) {
                LOGE("Reprocess Deferred work was failed");
            }
            if (NO_ERROR != waitDeferredWork(mJpegJob)) {
                LOGE("Jpeg Deferred work was failed");
            }
            m_postprocessor.stop();
            return rc;
        }
    }

    if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
        QCameraStream *pStream = NULL;
        for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
            pStream = pChannel->getStreamByIndex(i);
            if ((NULL != pStream) &&
                    (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
                break;
            }
        }
        if (pStream != NULL) {
            LOGD("REQUEST_FRAMES event for TNR snapshot");
            cam_stream_parm_buffer_t param;
            memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
            param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
            param.frameRequest.enableStream = 1;
            rc = pStream->setParameter(param);
            if (rc != NO_ERROR) {
                LOGE("Stream Event REQUEST_FRAMES failed");
            }
            goto end;
        }
    }

    // start snapshot channel
    if ((rc == NO_ERROR) && (NULL != pChannel)) {
        // Do not link metadata stream for 4K2k resolution
        // as CPP processing would be done on snapshot stream and not
        // reprocess stream
        if (!mParameters.is4k2kVideoResolution()) {
            // Find and try to link a metadata stream from preview channel
            QCameraChannel *pMetaChannel = NULL;
            QCameraStream *pMetaStream = NULL;
            QCameraStream *pPreviewStream = NULL;

            if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
                pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
                uint32_t streamNum = pMetaChannel->getNumOfStreams();
                QCameraStream *pStream = NULL;
                for (uint32_t i = 0 ; i < streamNum ; i++ ) {
                    pStream = pMetaChannel->getStreamByIndex(i);
                    if (NULL != pStream) {
                        if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
                            pMetaStream = pStream;
                        } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType())
                                && (!mParameters.isHfrMode())
                                && (mParameters.isLinkPreviewForLiveShot())) {
                            // Do not link preview stream for
                            // 1)HFR live snapshot,Thumbnail will not be derived from
                            //   preview for HFR live snapshot.
                            // 2)persist.camera.linkpreview is 0
                            pPreviewStream = pStream;
                        }
                    }
                }
            }

            if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
                rc = pChannel->linkStream(pMetaChannel, pMetaStream);
                if (NO_ERROR != rc) {
                    LOGE("Metadata stream link failed %d", rc);
                }
            }
            if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
                rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
                if (NO_ERROR != rc) {
                    LOGE("Preview stream link failed %d", rc);
                }
            }
        }
        rc = pChannel->start();
    }

end:
    if (rc != NO_ERROR) {
        rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
        rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : cancelLiveSnapshot
 *
 * DESCRIPTION: cancel current live snapshot request
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::cancelLiveSnapshot()
{
    int rc = NO_ERROR;
    if (mLiveSnapshotThread != 0) {
        pthread_join(mLiveSnapshotThread,NULL);
        mLiveSnapshotThread = 0;
    }
    bLiveSnapshot = false;
    rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
    if (!rc) {
        pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap");
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : cancelLiveSnapshot_internal
 *
 * DESCRIPTION: cancel live snapshot during recording
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::cancelLiveSnapshot_internal() {
    int rc = NO_ERROR;

    unconfigureAdvancedCapture();
    LOGH("Enable display frames again");
    setDisplaySkip(FALSE);

    //wait for deferred (reprocess and jpeg) threads to finish
    waitDeferredWork(mReprocJob);
    waitDeferredWork(mJpegJob);
    //stop post processor
    m_postprocessor.stop();

    // stop snapshot channel
    if (!mParameters.isTNRSnapshotEnabled()) {
        rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
    } else {
        QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
        if (NULL != pChannel) {
            QCameraStream *pStream = NULL;
            for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
                pStream = pChannel->getStreamByIndex(i);
                if ((NULL != pStream) &&
                        (CAM_STREAM_TYPE_SNAPSHOT ==
                        pStream->getMyType())) {
                    break;
                }
            }
            if (pStream != NULL) {
                LOGD("REQUEST_FRAMES event for TNR snapshot");
                cam_stream_parm_buffer_t param;
                memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
                param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
                param.frameRequest.enableStream = 0;
                rc = pStream->setParameter(param);
                if (rc != NO_ERROR) {
                    LOGE("Stream Event REQUEST_FRAMES failed");
                }
            }
        }
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : putParameters
 *
 * DESCRIPTION: put parameters string impl
 *
 * PARAMETERS :
 *   @parms   : parameters string to be released
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::putParameters(char *parms)
{
    free(parms);
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : sendCommand
 *
 * DESCRIPTION: send command impl
 *
 * PARAMETERS :
 *   @command : command to be executed
 *   @arg1    : optional argument 1
 *   @arg2    : optional argument 2
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::sendCommand(int32_t command,
        __unused int32_t &arg1, __unused int32_t &arg2)
{
    int rc = NO_ERROR;

    switch (command) {
#ifndef VANILLA_HAL
    case CAMERA_CMD_LONGSHOT_ON:
        arg1 = arg2 = 0;
        // Longshot can only be enabled when image capture
        // is not active.
        if ( !m_stateMachine.isCaptureRunning() ) {
            LOGI("Longshot Enabled");
            mLongshotEnabled = true;
            rc = mParameters.setLongshotEnable(mLongshotEnabled);

            // Due to recent buffer count optimizations
            // ZSL might run with considerably less buffers
            // when not in longshot mode. Preview needs to
            // restart in this case.
            if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
                QCameraChannel *pChannel = NULL;
                QCameraStream *pSnapStream = NULL;
                pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
                if (NULL != pChannel) {
                    QCameraStream *pStream = NULL;
                    for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
                        pStream = pChannel->getStreamByIndex(i);
                        if (pStream != NULL) {
                            if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
                                pSnapStream = pStream;
                                break;
                            }
                        }
                    }
                    if (NULL != pSnapStream) {
                        uint8_t required = 0;
                        required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
                        if (pSnapStream->getBufferCount() < required) {
                            // We restart here, to reset the FPS and no
                            // of buffers as per the requirement of longshot usecase.
                            arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
                            if (getRelatedCamSyncInfo()->sync_control ==
                                    CAM_SYNC_RELATED_SENSORS_ON) {
                                arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
                            }
                        }
                    }
                }
            }
            //
            mPrepSnapRun = false;
            mCACDoneReceived = FALSE;
        } else {
            rc = NO_INIT;
        }
        break;
    case CAMERA_CMD_LONGSHOT_OFF:
        if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
            cancelPicture();
            processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
            QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
            if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
                mCameraHandle->ops->stop_zsl_snapshot(
                        mCameraHandle->camera_handle,
                        pZSLChannel->getMyHandle());
            }
        }
        mPrepSnapRun = false;
        LOGI("Longshot Disabled");
        mLongshotEnabled = false;
        rc = mParameters.setLongshotEnable(mLongshotEnabled);
        mCACDoneReceived = FALSE;
        break;
    case CAMERA_CMD_HISTOGRAM_ON:
    case CAMERA_CMD_HISTOGRAM_OFF:
        rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
        LOGH("Histogram -> %s",
              mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
        break;
#endif
    case CAMERA_CMD_START_FACE_DETECTION:
    case CAMERA_CMD_STOP_FACE_DETECTION:
        mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
        rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
        LOGH("FaceDetection -> %s",
              mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
        break;
#ifndef VANILLA_HAL
    case CAMERA_CMD_HISTOGRAM_SEND_DATA:
#endif
    default:
        rc = NO_ERROR;
        break;
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : registerFaceImage
 *
 * DESCRIPTION: register face image impl
 *
 * PARAMETERS :
 *   @img_ptr : ptr to image buffer
 *   @config  : ptr to config struct about input image info
 *   @faceID  : [OUT] face ID to uniquely identifiy the registered face image
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
                                                 cam_pp_offline_src_config_t *config,
                                                 int32_t &faceID)
{
    int rc = NO_ERROR;
    faceID = -1;

    if (img_ptr == NULL || config == NULL) {
        LOGE("img_ptr or config is NULL");
        return BAD_VALUE;
    }

    // allocate ion memory for source image
    QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
    if (imgBuf == NULL) {
        LOGE("Unable to new heap memory obj for image buf");
        return NO_MEMORY;
    }

    rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len);
    if (rc < 0) {
        LOGE("Unable to allocate heap memory for image buf");
        delete imgBuf;
        return NO_MEMORY;
    }

    void *pBufPtr = imgBuf->getPtr(0);
    if (pBufPtr == NULL) {
        LOGE("image buf is NULL");
        imgBuf->deallocate();
        delete imgBuf;
        return NO_MEMORY;
    }
    memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
    //Do cache ops before sending for reprocess
    imgBuf->cacheOps(0, ION_IOC_CLEAN_INV_CACHES);

    cam_pp_feature_config_t pp_feature;
    memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
    pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
    QCameraReprocessChannel *pChannel =
        addOfflineReprocChannel(*config, pp_feature, NULL, NULL);

    if (pChannel == NULL) {
        LOGE("fail to add offline reprocess channel");
        imgBuf->deallocate();
        delete imgBuf;
        return UNKNOWN_ERROR;
    }

    rc = pChannel->start();
    if (rc != NO_ERROR) {
        LOGE("Cannot start reprocess channel");
        imgBuf->deallocate();
        delete imgBuf;
        delete pChannel;
        return rc;
    }

    ssize_t bufSize = imgBuf->getSize(0);
    if (BAD_INDEX != bufSize) {
        rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0),
                (size_t)bufSize, faceID);
    } else {
        LOGE("Failed to retrieve buffer size (bad index)");
        return UNKNOWN_ERROR;
    }

    // done with register face image, free imgbuf and delete reprocess channel
    imgBuf->deallocate();
    delete imgBuf;
    imgBuf = NULL;
    pChannel->stop();
    delete pChannel;
    pChannel = NULL;

    return rc;
}

/*===========================================================================
 * FUNCTION   : release
 *
 * DESCRIPTION: release camera resource impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::release()
{
    // stop and delete all channels
    for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
        if (m_channels[i] != NULL) {
            stopChannel((qcamera_ch_type_enum_t)i);
            delChannel((qcamera_ch_type_enum_t)i);
        }
    }

    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : dump
 *
 * DESCRIPTION: camera status dump impl
 *
 * PARAMETERS :
 *   @fd      : fd for the buffer to be dumped with camera status
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::dump(int fd)
{
    dprintf(fd, "\n Camera HAL information Begin \n");
    dprintf(fd, "Camera ID: %d \n", mCameraId);
    dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
    dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
    dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
    dprintf(fd, "\n Camera HAL information End \n");

    /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
       debug level property */
    mParameters.updateDebugLevel();
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : processAPI
 *
 * DESCRIPTION: process API calls from upper layer
 *
 * PARAMETERS :
 *   @api         : API to be processed
 *   @api_payload : ptr to API payload if any
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
{
    int ret = DEAD_OBJECT;

    if (m_smThreadActive) {
        ret = m_stateMachine.procAPI(api, api_payload);
    }

    return ret;
}

/*===========================================================================
 * FUNCTION   : processEvt
 *
 * DESCRIPTION: process Evt from backend via mm-camera-interface
 *
 * PARAMETERS :
 *   @evt         : event type to be processed
 *   @evt_payload : ptr to event payload if any
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
{
    return m_stateMachine.procEvt(evt, evt_payload);
}

/*===========================================================================
 * FUNCTION   : processSyncEvt
 *
 * DESCRIPTION: process synchronous Evt from backend
 *
 * PARAMETERS :
 *   @evt         : event type to be processed
 *   @evt_payload : ptr to event payload if any
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
{
    int rc = NO_ERROR;

    pthread_mutex_lock(&m_evtLock);
    rc =  processEvt(evt, evt_payload);
    if (rc == NO_ERROR) {
        memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
        while (m_evtResult.request_api != evt) {
            pthread_cond_wait(&m_evtCond, &m_evtLock);
        }
        rc =  m_evtResult.status;
    }
    pthread_mutex_unlock(&m_evtLock);

    return rc;
}

/*===========================================================================
 * FUNCTION   : evtHandle
 *
 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
 *
 * PARAMETERS :
 *   @camera_handle : event type to be processed
 *   @evt           : ptr to event
 *   @user_data     : user data ptr
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
                                          mm_camera_event_t *evt,
                                          void *user_data)
{
    QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
    if (obj && evt) {
        mm_camera_event_t *payload =
            (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
        if (NULL != payload) {
            *payload = *evt;
            //peek into the event, if this is an eztune event from server,
            //then we don't need to post it to the SM Qs, we shud directly
            //spawn a thread and get the job done (jpeg or raw snapshot)
            switch (payload->server_event_type) {
                case CAM_EVENT_TYPE_INT_TAKE_JPEG:
                    //Received JPEG trigger from eztune
                    if (false == obj->m_bIntJpegEvtPending) {
                        pthread_mutex_lock(&obj->m_int_lock);
                        obj->m_bIntJpegEvtPending = true;
                        pthread_mutex_unlock(&obj->m_int_lock);
                        obj->takePictureInternal();
                    }
                    free(payload);
                    break;
                case CAM_EVENT_TYPE_INT_TAKE_RAW:
                    //Received RAW trigger from eztune
                    if (false == obj->m_bIntRawEvtPending) {
                        pthread_mutex_lock(&obj->m_int_lock);
                        obj->m_bIntRawEvtPending = true;
                        pthread_mutex_unlock(&obj->m_int_lock);
                        obj->takePictureInternal();
                    }
                    free(payload);
                    break;
                case CAM_EVENT_TYPE_DAEMON_DIED:
                    {
                        Mutex::Autolock l(obj->mDefLock);
                        obj->mDefCond.broadcast();
                        LOGH("broadcast mDefCond signal\n");
                    }
                default:
                    obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
                    break;
            }
        }
    } else {
        LOGE("NULL user_data");
    }
}

/*===========================================================================
 * FUNCTION   : jpegEvtHandle
 *
 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
 *
 * PARAMETERS :
 *   @status    : status of jpeg job
 *   @client_hdl: jpeg client handle
 *   @jobId     : jpeg job Id
 *   @p_ouput   : ptr to jpeg output result struct
 *   @userdata  : user data ptr
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
                                              uint32_t /*client_hdl*/,
                                              uint32_t jobId,
                                              mm_jpeg_output_t *p_output,
                                              void *userdata)
{
    QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
    if (obj) {
        qcamera_jpeg_evt_payload_t *payload =
            (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
        if (NULL != payload) {
            memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
            payload->status = status;
            payload->jobId = jobId;
            if (p_output != NULL) {
                payload->out_data = *p_output;
            }
            obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
        }
    } else {
        LOGE("NULL user_data");
    }
}

/*===========================================================================
 * FUNCTION   : thermalEvtHandle
 *
 * DESCRIPTION: routine to handle thermal event notification
 *
 * PARAMETERS :
 *   @level      : thermal level
 *   @userdata   : userdata passed in during registration
 *   @data       : opaque data from thermal client
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::thermalEvtHandle(
        qcamera_thermal_level_enum_t *level, void *userdata, void *data)
{
    if (!mCameraOpened) {
        LOGH("Camera is not opened, no need to handle thermal evt");
        return NO_ERROR;
    }

    // Make sure thermal events are logged
    LOGH("level = %d, userdata = %p, data = %p",
         *level, userdata, data);
    //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
    // becomes an aync call. This also means we can only pass payload
    // by value, not by address.
    return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
}

/*===========================================================================
 * FUNCTION   : sendEvtNotify
 *
 * DESCRIPTION: send event notify to notify thread
 *
 * PARAMETERS :
 *   @msg_type: msg type to be sent
 *   @ext1    : optional extension1
 *   @ext2    : optional extension2
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
                                                 int32_t ext1,
                                                 int32_t ext2)
{
    qcamera_callback_argm_t cbArg;
    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
    cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
    cbArg.msg_type = msg_type;
    cbArg.ext1 = ext1;
    cbArg.ext2 = ext2;
    return m_cbNotifier.notifyCallback(cbArg);
}

/*===========================================================================
 * FUNCTION   : processAEInfo
 *
 * DESCRIPTION: process AE updates
 *
 * PARAMETERS :
 *   @ae_params: current AE parameters
 *
 * RETURN     : None
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
{
    mParameters.updateAEInfo(ae_params);
    if (mParameters.isInstantAECEnabled()) {
        // Reset Instant AEC info only if instant aec enabled.
        bool bResetInstantAec = false;
        if (ae_params.settled) {
            // If AEC settled, reset instant AEC
            bResetInstantAec = true;
        } else if ((mParameters.isInstantCaptureEnabled()) &&
                (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
            // if AEC not settled, and instant capture enabled,
            // reset instant AEC only when frame count is
            // more or equal to AEC frame bound value.
            bResetInstantAec = true;
        } else if ((mParameters.isInstantAECEnabled()) &&
                (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
            // if AEC not settled, and only instant AEC enabled,
            // reset instant AEC only when frame count is
            // more or equal to AEC skip display frame bound value.
            bResetInstantAec = true;
        }

        if (bResetInstantAec) {
            LOGD("setting instant AEC to false");
            mParameters.setInstantAEC(false, true);
            mInstantAecFrameCount = 0;
        }
    }
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : processFocusPositionInfo
 *
 * DESCRIPTION: process AF updates
 *
 * PARAMETERS :
 *   @cur_pos_info: current lens position
 *
 * RETURN     : None
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
{
    mParameters.updateCurrentFocusPosition(cur_pos_info);
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : processAutoFocusEvent
 *
 * DESCRIPTION: process auto focus event
 *
 * PARAMETERS :
 *   @focus_data: struct containing auto focus result info
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
{
    int32_t ret = NO_ERROR;
    LOGH("E");

    if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
        // Ignore focus updates
        LOGH("X Secondary Camera, no need to process!! ");
        return ret;
    }
    cam_focus_mode_type focusMode = mParameters.getFocusMode();
    LOGH("[AF_DBG]  focusMode=%d, focusState=%d isDepth=%d",
             focusMode, focus_data.focus_state, focus_data.isDepth);

    switch (focusMode) {
    case CAM_FOCUS_MODE_AUTO:
    case CAM_FOCUS_MODE_MACRO:
        // ignore AF event if AF was already cancelled meanwhile
        if (!mActiveAF) {
            break;
        }
        // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
        if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
                (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
            ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
            mActiveAF = false; // reset the mActiveAF in this special case
            break;
        }

        //while transitioning from CAF->Auto/Macro, we might receive CAF related
        //events (PASSIVE_*) due to timing. Ignore such events if any.
        if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
                (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
                (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
            break;
        }

        //This is just an intermediate update to HAL indicating focus is in progress. No need
        //to send this event to app. Same applies to INACTIVE state as well.
        if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
                (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
            break;
        }
        // update focus distance
        mParameters.updateFocusDistances(&focus_data.focus_dist);

        //flush any old snapshot frames in ZSL Q which are not focused.
        if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
            QCameraPicChannel *pZSLChannel =
                    (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
            if (NULL != pZSLChannel) {
                //flush the zsl-buffer
                uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
                LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
                pZSLChannel->flushSuperbuffer(flush_frame_idx);
            }
        }

        //send event to app finally
        LOGI("Send AF DOne event to app");
        ret = sendEvtNotify(CAMERA_MSG_FOCUS,
                            (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
        break;
    case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
    case CAM_FOCUS_MODE_CONTINOUS_PICTURE:

        // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
        if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
                (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
            ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
            mActiveAF = false; // reset the mActiveAF in this special case
            break;
        }

        //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
        //process/wait for only ACTIVE_* events.
        if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
                (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
                (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
            break;
        }

        if (!bDepthAFCallbacks && focus_data.isDepth &&
                (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) {
            LOGD("Skip sending scan state to app, if depth focus");
            break;
        }

        //These are the AF states for which we need to send notification to app in CAF mode.
        //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
        //AF is triggered while in CAF mode)
        if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
                (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
                (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
                (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {

            // update focus distance
            mParameters.updateFocusDistances(&focus_data.focus_dist);

            if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
                QCameraPicChannel *pZSLChannel =
                        (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
                if (NULL != pZSLChannel) {
                    //flush the zsl-buffer
                    uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
                    LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
                    pZSLChannel->flushSuperbuffer(flush_frame_idx);
                }
            }

            if (mActiveAF) {
                LOGI("Send AF Done event to app");
            }
            ret = sendEvtNotify(CAMERA_MSG_FOCUS,
                    ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
                    (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
        }
        ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
                (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
        break;
    case CAM_FOCUS_MODE_INFINITY:
    case CAM_FOCUS_MODE_FIXED:
    case CAM_FOCUS_MODE_EDOF:
    default:
        LOGH("no ops for autofocus event in focusmode %d", focusMode);
        break;
    }

    //Reset mActiveAF once we receive focus done event
    if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
            (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
        mActiveAF = false;
    }

    LOGH("X");
    return ret;
}

/*===========================================================================
 * FUNCTION   : processZoomEvent
 *
 * DESCRIPTION: process zoom event
 *
 * PARAMETERS :
 *   @crop_info : crop info as a result of zoom operation
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
{
    int32_t ret = NO_ERROR;

    for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
        if (m_channels[i] != NULL) {
            ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
        }
    }
    return ret;
}

/*===========================================================================
 * FUNCTION   : processZSLCaptureDone
 *
 * DESCRIPTION: process ZSL capture done events
 *
 * PARAMETERS : None
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processZSLCaptureDone()
{
    int rc = NO_ERROR;

    if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
        rc = unconfigureAdvancedCapture();
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : processRetroAECUnlock
 *
 * DESCRIPTION: process retro burst AEC unlock events
 *
 * PARAMETERS : None
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processRetroAECUnlock()
{
    int rc = NO_ERROR;

    LOGH("LED assisted AF Release AEC Lock");
    rc = mParameters.setAecLock("false");
    if (NO_ERROR != rc) {
        LOGE("Error setting AEC lock");
        return rc;
    }

    rc = mParameters.commitParameters();
    if (NO_ERROR != rc) {
        LOGE("Error during camera parameter commit");
    } else {
        m_bLedAfAecLock = FALSE;
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : processHDRData
 *
 * DESCRIPTION: process HDR scene events
 *
 * PARAMETERS :
 *   @hdr_scene : HDR scene event data
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processHDRData(
        __unused cam_asd_hdr_scene_data_t hdr_scene)
{
    int rc = NO_ERROR;

#ifndef VANILLA_HAL
    if (hdr_scene.is_hdr_scene &&
      (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
      mParameters.isAutoHDREnabled()) {
        m_HDRSceneEnabled = true;
    } else {
        m_HDRSceneEnabled = false;
    }
    mParameters.setHDRSceneEnable(m_HDRSceneEnabled);

    if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {

        size_t data_len = sizeof(int);
        size_t buffer_len = 1 *sizeof(int)       //meta type
                          + 1 *sizeof(int)       //data len
                          + 1 *sizeof(int);      //data
        camera_memory_t *hdrBuffer = mGetMemory(-1,
                                                 buffer_len,
                                                 1,
                                                 mCallbackCookie);
        if ( NULL == hdrBuffer ) {
            LOGE("Not enough memory for auto HDR data");
            return NO_MEMORY;
        }

        int *pHDRData = (int *)hdrBuffer->data;
        if (pHDRData == NULL) {
            LOGE("memory data ptr is NULL");
            return UNKNOWN_ERROR;
        }

        pHDRData[0] = CAMERA_META_DATA_HDR;
        pHDRData[1] = (int)data_len;
        pHDRData[2] = m_HDRSceneEnabled;

        qcamera_callback_argm_t cbArg;
        memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
        cbArg.cb_type = QCAMERA_DATA_CALLBACK;
        cbArg.msg_type = CAMERA_MSG_META_DATA;
        cbArg.data = hdrBuffer;
        cbArg.user_data = hdrBuffer;
        cbArg.cookie = this;
        cbArg.release_cb = releaseCameraMemory;
        rc = m_cbNotifier.notifyCallback(cbArg);
        if (rc != NO_ERROR) {
            LOGE("fail sending auto HDR notification");
            hdrBuffer->release(hdrBuffer);
        }
    }

    LOGH("hdr_scene_data: processHDRData: %d %f",
          hdr_scene.is_hdr_scene,
          hdr_scene.hdr_confidence);

#endif
  return rc;
}

/*===========================================================================
 * FUNCTION   : processLEDCalibration
 *
 * DESCRIPTION: process LED calibration result
 *
 * PARAMETERS :
 *   @value : Calibaration result
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processLEDCalibration(int32_t value)
{
    int32_t rc = NO_ERROR;
#ifndef VANILLA_HAL
    if (mParameters.getDualLedCalibration()) {
        LOGH("Dual LED calibration value = %d", value);
        int32_t data_len = sizeof(value);
        int32_t buffer_len = sizeof(int)       //meta type
                + sizeof(int)                  //data len
                + data_len;                    //data
        camera_memory_t *buffer = mGetMemory(-1,
                buffer_len, 1, mCallbackCookie);
        if ( NULL == buffer ) {
            LOGE("Not enough memory for data");
            return NO_MEMORY;
        }

        int *pData = (int *)buffer->data;
        if (pData == NULL) {
            LOGE("memory data ptr is NULL");
            buffer->release(buffer);
            return UNKNOWN_ERROR;
        }

        pData[0] = QCAMERA_METADATA_LED_CALIB;
        pData[1] = (int)data_len;
        pData[2] = value;

        qcamera_callback_argm_t cbArg;
        memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
        cbArg.cb_type = QCAMERA_DATA_CALLBACK;
        cbArg.msg_type = CAMERA_MSG_META_DATA;
        cbArg.data = buffer;
        cbArg.user_data = buffer;
        cbArg.cookie = this;
        cbArg.release_cb = releaseCameraMemory;
        int32_t rc = m_cbNotifier.notifyCallback(cbArg);
        if (rc != NO_ERROR) {
            LOGE("fail sending notification");
            buffer->release(buffer);
        }
    }
#else
    (void)value;  // unused
#endif
    return rc;
}


/*===========================================================================
 * FUNCTION   : transAwbMetaToParams
 *
 * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
 *
 * PARAMETERS :
 *   @awb_params : awb params from metadata callback
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
{
    mParameters.updateAWBParams(awb_params);
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : processPrepSnapshotDone
 *
 * DESCRIPTION: process prep snapshot done event
 *
 * PARAMETERS :
 *   @prep_snapshot_state  : state of prepare snapshot done. In other words,
 *                           i.e. whether need future frames for capture.
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
                        cam_prep_snapshot_state_t prep_snapshot_state)
{
    int32_t ret = NO_ERROR;
    LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
            prep_snapshot_state);
    if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
        prep_snapshot_state == NEED_FUTURE_FRAME) {
        LOGH("already handled in mm-camera-intf, no ops here");
        if (isRetroPicture()) {
            mParameters.setAecLock("true");
            mParameters.commitParameters();
            m_bLedAfAecLock = TRUE;
        }
    }
    return ret;
}

/*===========================================================================
 * FUNCTION   : processASDUpdate
 *
 * DESCRIPTION: process ASD update event
 *
 * PARAMETERS :
 *   @scene: selected scene mode
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processASDUpdate(
        __unused cam_asd_decision_t asd_decision)
{
#ifndef VANILLA_HAL
    if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
        size_t data_len = sizeof(cam_auto_scene_t);
        size_t buffer_len = 1 *sizeof(int)       //meta type
                + 1 *sizeof(int)       //data len
                + data_len;            //data
        camera_memory_t *asdBuffer = mGetMemory(-1,
                buffer_len, 1, mCallbackCookie);
        if ( NULL == asdBuffer ) {
            LOGE("Not enough memory for histogram data");
            return NO_MEMORY;
        }

        int *pASDData = (int *)asdBuffer->data;
        if (pASDData == NULL) {
            LOGE("memory data ptr is NULL");
            return UNKNOWN_ERROR;
        }

        pASDData[0] = CAMERA_META_DATA_ASD;
        pASDData[1] = (int)data_len;
        pASDData[2] = asd_decision.detected_scene;

        qcamera_callback_argm_t cbArg;
        memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
        cbArg.cb_type = QCAMERA_DATA_CALLBACK;
        cbArg.msg_type = CAMERA_MSG_META_DATA;
        cbArg.data = asdBuffer;
        cbArg.user_data = asdBuffer;
        cbArg.cookie = this;
        cbArg.release_cb = releaseCameraMemory;
        int32_t rc = m_cbNotifier.notifyCallback(cbArg);
        if (rc != NO_ERROR) {
            LOGE("fail sending notification");
            asdBuffer->release(asdBuffer);
        }
    }
#endif
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : processJpegNotify
 *
 * DESCRIPTION: process jpeg event
 *
 * PARAMETERS :
 *   @jpeg_evt: ptr to jpeg event payload
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
{
    return m_postprocessor.processJpegEvt(jpeg_evt);
}


/*===========================================================================
 * FUNCTION   : processDualCamFovControl
 *
 * DESCRIPTION: Based on the result collected from FOV control-
 *              1. Switch the master camera if needed
 *              2. Toggle the Low Power Mode for slave camera
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::processDualCamFovControl()
{
   uint32_t activeCameras;
   bool bundledSnapshot;
   fov_control_result_t fovControlResult;
   cam_sync_type_t camMasterSnapshot;

    if (!isDualCamera()) {
        return;
    }

    fovControlResult = m_pFovControl->getFovControlResult();

    if (fovControlResult.isValid) {
        activeCameras = fovControlResult.activeCameras;
        bundledSnapshot = fovControlResult.snapshotPostProcess;
        camMasterSnapshot = fovControlResult.camMasterPreview;

        processCameraControl(activeCameras, bundledSnapshot);
        switchCameraCb(fovControlResult.camMasterPreview);
    }
}

/*===========================================================================
 * FUNCTION   : processCameraControl
 *
 * DESCRIPTION: Suspend and resume camera
 *
 * PARAMETERS :
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processCameraControl(
        uint32_t activeCameras,
        bool     bundledSnapshot)
{
    int32_t ret = NO_ERROR;

    //Update camera status to internal channel
    for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
        if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
            ret = m_channels[i]->processCameraControl(activeCameras, bundledSnapshot);
            if (ret != NO_ERROR) {
                LOGE("Channel Switch Failed");
                break;
            }
        }
    }

    if ((activeCameras != mActiveCameras) ||
            ((activeCameras == MM_CAMERA_DUAL_CAM) && (bundledSnapshot != mBundledSnapshot))) {

        if (activeCameras != mActiveCameras) {
            //Set camera controls to parameter and back-end
            ret = mParameters.setCameraControls(activeCameras);
        }

        mParameters.setBundledSnapshot(bundledSnapshot);
        mParameters.setNumOfSnapshot();

        LOGH("mActiveCameras = %d to %d, bundledSnapshot = %d to %d",
                mActiveCameras, activeCameras, mBundledSnapshot, bundledSnapshot);
        mActiveCameras   = activeCameras;
        mBundledSnapshot = bundledSnapshot;
    }

    return ret;
}

/*===========================================================================
 * FUNCTION   : switchCameraCb
 *
 * DESCRIPTION: switch camera's in case of dual camera
 *
 * PARAMETERS :
 * @camMaster : Master camera
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::switchCameraCb(uint32_t camMaster)
{
    int32_t ret = NO_ERROR;

    if (mActiveCameras & camMaster) {
        for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
            if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
                ret = m_channels[i]->switchChannelCb(camMaster);
                if (ret != NO_ERROR) {
                    LOGE("Channel Switch Failed");
                    break;
                }
            }
        }

        if (mMasterCamera != camMaster) {
            if (ret == NO_ERROR) {
                //Trigger Event to modules to update Master info
                mParameters.setSwitchCamera(camMaster);
            }
        }
        // Update master camera
        mMasterCamera = camMaster;
    }

    return ret;
}

/*===========================================================================
 * FUNCTION   : lockAPI
 *
 * DESCRIPTION: lock to process API
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::lockAPI()
{
    pthread_mutex_lock(&m_lock);
}

/*===========================================================================
 * FUNCTION   : waitAPIResult
 *
 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
 *              return only cerntain API event type arrives
 *
 * PARAMETERS :
 *   @api_evt : API event type
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
        qcamera_api_result_t *apiResult)
{
    LOGD("wait for API result of evt (%d)", api_evt);
    int resultReceived = 0;
    while  (!resultReceived) {
        pthread_cond_wait(&m_cond, &m_lock);
        if (m_apiResultList != NULL) {
            api_result_list *apiResultList = m_apiResultList;
            api_result_list *apiResultListPrevious = m_apiResultList;
            while (apiResultList != NULL) {
                if (apiResultList->result.request_api == api_evt) {
                    resultReceived = 1;
                    *apiResult = apiResultList->result;
                    apiResultListPrevious->next = apiResultList->next;
                    if (apiResultList == m_apiResultList) {
                        m_apiResultList = apiResultList->next;
                    }
                    free(apiResultList);
                    break;
                }
                else {
                    apiResultListPrevious = apiResultList;
                    apiResultList = apiResultList->next;
                }
            }
        }
    }
    LOGD("return (%d) from API result wait for evt (%d)",
           apiResult->status, api_evt);
}


/*===========================================================================
 * FUNCTION   : unlockAPI
 *
 * DESCRIPTION: API processing is done, unlock
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::unlockAPI()
{
    pthread_mutex_unlock(&m_lock);
}

/*===========================================================================
 * FUNCTION   : signalAPIResult
 *
 * DESCRIPTION: signal condition viarable that cerntain API event type arrives
 *
 * PARAMETERS :
 *   @result  : API result
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
{

    pthread_mutex_lock(&m_lock);
    api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
    if (apiResult == NULL) {
        LOGE("ERROR: malloc for api result failed, Result will not be sent");
        goto malloc_failed;
    }
    apiResult->result = *result;
    apiResult->next = NULL;
    if (m_apiResultList == NULL) m_apiResultList = apiResult;
    else {
        api_result_list *apiResultList = m_apiResultList;
        while(apiResultList->next != NULL) apiResultList = apiResultList->next;
        apiResultList->next = apiResult;
    }
malloc_failed:
    pthread_cond_broadcast(&m_cond);
    pthread_mutex_unlock(&m_lock);
}

/*===========================================================================
 * FUNCTION   : signalEvtResult
 *
 * DESCRIPTION: signal condition variable that certain event was processed
 *
 * PARAMETERS :
 *   @result  : Event result
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
{
    pthread_mutex_lock(&m_evtLock);
    m_evtResult = *result;
    pthread_cond_signal(&m_evtCond);
    pthread_mutex_unlock(&m_evtLock);
}

int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
{
    int32_t rc = NO_ERROR;
    cam_dimension_t str_dim,max_dim;
    QCameraChannel *pChannel;

    max_dim.width = 0;
    max_dim.height = 0;

    for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
        if (m_channels[j] != NULL) {
            pChannel = m_channels[j];
            for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
                QCameraStream *pStream = pChannel->getStreamByIndex(i);
                if (pStream != NULL) {
                    if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
                            || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
                        continue;
                    }
                    pStream->getFrameDimension(str_dim);
                    if (str_dim.width > max_dim.width) {
                        max_dim.width = str_dim.width;
                    }
                    if (str_dim.height > max_dim.height) {
                        max_dim.height = str_dim.height;
                    }
                }
            }
        }
    }

    for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
        QCameraStream *pStream = curChannel->getStreamByIndex(i);
        if (pStream != NULL) {
            if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
                    || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
                continue;
            }
            pStream->getFrameDimension(str_dim);
            if (str_dim.width > max_dim.width) {
                max_dim.width = str_dim.width;
            }
            if (str_dim.height > max_dim.height) {
                max_dim.height = str_dim.height;
            }
        }
    }
    rc = mParameters.updateRAW(max_dim);
    return rc;
}

/*===========================================================================
 * FUNCTION   : getPaddingInfo
 *
 * DESCRIPTION: calculate padding per stream
 *
 * PARAMETERS :
 *   @streamType  : type of stream to be added
 *   @padding_info : Padding info. Output
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::getPaddingInfo(cam_stream_type_t streamType,
        cam_padding_info_t *padding_info)
{
    int32_t rc = NO_ERROR;
    if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
        cam_analysis_info_t analysisInfo;
        cam_feature_mask_t featureMask;

        featureMask = 0;
        mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask);
        rc = mParameters.getAnalysisInfo(
                ((mParameters.getRecordingHintValue() == true) &&
                 mParameters.fdModeInVideo()),
                featureMask,
                &analysisInfo);
        if (rc != NO_ERROR) {
            LOGE("getAnalysisInfo failed, ret = %d", rc);
            return rc;
        }

        *padding_info = analysisInfo.analysis_padding_info;
    } else {
        *padding_info =
                gCamCapability[mCameraId]->padding_info;
        if (streamType == CAM_STREAM_TYPE_PREVIEW || streamType == CAM_STREAM_TYPE_POSTVIEW) {
            padding_info->width_padding = mSurfaceStridePadding;
            padding_info->height_padding = CAM_PAD_TO_2;
        }
        if((!needReprocess())
                || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
                || (!mParameters.isLLNoiseEnabled())) {
            padding_info->offset_info.offset_x = 0;
            padding_info->offset_info.offset_y = 0;
        }
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : addStreamToChannel
 *
 * DESCRIPTION: add a stream into a channel
 *
 * PARAMETERS :
 *   @pChannel   : ptr to channel obj
 *   @streamType : type of stream to be added
 *   @streamCB   : callback of stream
 *   @userData   : user data ptr to callback
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
                                                      cam_stream_type_t streamType,
                                                      stream_cb_routine streamCB,
                                                      void *userData)
{
    int32_t rc = NO_ERROR;
    QCameraHeapMemory *pStreamInfo = NULL;
    uint32_t cam_type = MM_CAMERA_TYPE_MAIN;
    bool needAuxStream = FALSE;

    if (streamType == CAM_STREAM_TYPE_RAW) {
        prepareRawStream(pChannel);
    }

    if (isDualCamera()) {
        if (!((mParameters.isDCmAsymmetricSnapMode()) &&
                (streamType == CAM_STREAM_TYPE_SNAPSHOT))) {
            cam_type |= MM_CAMERA_TYPE_AUX;
        } else {
            needAuxStream = TRUE;
        }
    }

    pStreamInfo = allocateStreamInfoBuf(streamType,
            getStreamRefCount(streamType, cam_type), cam_type);
    if (pStreamInfo == NULL) {
        LOGE("no mem for stream info buf");
        return NO_MEMORY;
    }

    bool bDynAllocBuf = false;
    if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
        bDynAllocBuf = true;
    }

    cam_padding_info_t padding_info;
    getPaddingInfo(streamType, &padding_info);

    bool deferAllocation = needDeferred(streamType);
    LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
            deferAllocation, bDynAllocBuf, streamType);
    rc = pChannel->addStream(*this,
            pStreamInfo, NULL, &padding_info,
            streamCB, userData, bDynAllocBuf,
            deferAllocation, ROTATE_0, cam_type);

    if (rc != NO_ERROR) {
        LOGE("add stream type (%d) cam = %d failed, ret = %d",
               streamType, cam_type, rc);
        return rc;
    }

    /*Add stream for Asymmetric dual camera use case*/
    if (needAuxStream) {
        cam_type = MM_CAMERA_TYPE_AUX;
        pStreamInfo = allocateStreamInfoBuf(streamType,
                getStreamRefCount(streamType, cam_type), cam_type);
        if (pStreamInfo == NULL) {
            LOGE("no mem for stream info buf");
            return NO_MEMORY;
        }
        rc = pChannel->addStream(*this,
                pStreamInfo, NULL, &padding_info,
                streamCB, userData, bDynAllocBuf,
                deferAllocation, ROTATE_0, cam_type);
        if (rc != NO_ERROR) {
            LOGE("add stream type (%d) cam = %d failed, ret = %d",
                   streamType, cam_type, rc);
            return rc;
        }
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : addPreviewChannel
 *
 * DESCRIPTION: add a preview channel that contains a preview stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addPreviewChannel()
{
    int32_t rc = NO_ERROR;
    QCameraChannel *pChannel = NULL;
    char value[PROPERTY_VALUE_MAX];
    bool raw_yuv = false;


    if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
        // if we had preview channel before, delete it first
        delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
        m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for preview channel");
        return NO_MEMORY;
    }

    // preview only channel, don't need bundle attr and cb
    rc = pChannel->init(NULL, NULL, NULL);
    if (rc != NO_ERROR) {
        LOGE("init preview channel failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    // meta data stream always coexists with preview if applicable
    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
            metadata_stream_cb_routine, this);
    if (rc != NO_ERROR) {
        LOGE("add metadata stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    if (isRdiMode()) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
                rdi_mode_stream_cb_routine, this);
    } else {
        if (isNoDisplayMode()) {
            rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                    nodisplay_preview_stream_cb_routine, this);
        } else {
            rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                    preview_stream_cb_routine, this);
            if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
                pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
                        synchronous_stream_cb_routine);
            }
        }
    }

    if (rc != NO_ERROR) {
        LOGE("add raw/preview stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    if (((mParameters.fdModeInVideo())
            || (mParameters.getDcrf() == true)
            || (mParameters.getRecordingHintValue() != true))
            && (!isSecureMode())) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
                NULL, this);
        if (rc != NO_ERROR) {
            LOGE("add Analysis stream failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    }

    property_get("persist.camera.raw_yuv", value, "0");
    raw_yuv = atoi(value) > 0 ? true : false;
    if ( raw_yuv ) {
        rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
                preview_raw_stream_cb_routine,this);
        if ( rc != NO_ERROR ) {
            LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
            delete pChannel;
            return rc;
        }
    }

    if (rc != NO_ERROR) {
        LOGE("add preview stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
    return rc;
}

/*===========================================================================
 * FUNCTION   : addVideoChannel
 *
 * DESCRIPTION: add a video channel that contains a video stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addVideoChannel()
{
    int32_t rc = NO_ERROR;
    QCameraVideoChannel *pChannel = NULL;

    if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
        // if we had video channel before, delete it first
        delete m_channels[QCAMERA_CH_TYPE_VIDEO];
        m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
    pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for video channel");
        return NO_MEMORY;
    }

    if (isLowPowerMode()) {
        mm_camera_channel_attr_t attr;
        memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
        attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
        attr.look_back = 0; //wait for future frame for liveshot
        attr.post_frame_skip = mParameters.getZSLBurstInterval();
        attr.water_mark = 1; //hold min buffers possible in Q
        attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
        rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
    } else {
        // preview only channel, don't need bundle attr and cb
        rc = pChannel->init(NULL, NULL, NULL);
    }

    if (rc != 0) {
        LOGE("init video channel failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
            video_stream_cb_routine, this);

    if (rc != NO_ERROR) {
        LOGE("add video stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
    return rc;
}

/*===========================================================================
 * FUNCTION   : addSnapshotChannel
 *
 * DESCRIPTION: add a snapshot channel that contains a snapshot stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 * NOTE       : Add this channel for live snapshot usecase. Regular capture will
 *              use addCaptureChannel.
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addSnapshotChannel()
{
    int32_t rc = NO_ERROR;
    QCameraChannel *pChannel = NULL;

    if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
        // if we had ZSL channel before, delete it first
        delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
        m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for snapshot channel");
        return NO_MEMORY;
    }

    mm_camera_channel_attr_t attr;
    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
    attr.look_back = 0; //wait for future frame for liveshot
    attr.post_frame_skip = mParameters.getZSLBurstInterval();
    attr.water_mark = 1; //hold min buffers possible in Q
    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
    attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
    rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
    if (rc != NO_ERROR) {
        LOGE("init snapshot channel failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
            NULL, NULL);
    if (rc != NO_ERROR) {
        LOGE("add snapshot stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
    return rc;
}

/*===========================================================================
 * FUNCTION   : addRawChannel
 *
 * DESCRIPTION: add a raw channel that contains a raw image stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addRawChannel()
{
    int32_t rc = NO_ERROR;
    QCameraChannel *pChannel = NULL;

    if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
        // if we had raw channel before, delete it first
        delete m_channels[QCAMERA_CH_TYPE_RAW];
        m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for raw channel");
        return NO_MEMORY;
    }

    if (mParameters.getofflineRAW()) {
        mm_camera_channel_attr_t attr;
        memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
        attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
        attr.look_back = mParameters.getZSLBackLookCount();
        attr.post_frame_skip = mParameters.getZSLBurstInterval();
        attr.water_mark = 1;
        attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
        rc = pChannel->init(&attr, raw_channel_cb_routine, this);
        if (rc != NO_ERROR) {
            LOGE("init RAW channel failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    } else {
        rc = pChannel->init(NULL, NULL, NULL);
        if (rc != NO_ERROR) {
            LOGE("init raw channel failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    }

    if (!mParameters.isZSLMode()) {
        // meta data stream always coexists with snapshot in regular RAW capture case
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
                metadata_stream_cb_routine, this);
        if (rc != NO_ERROR) {
            LOGE("add metadata stream failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    }

    if (mParameters.getofflineRAW()) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
                NULL, this);
    } else if(isSecureMode()) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
                secure_stream_cb_routine, this);
    } else {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
                raw_stream_cb_routine, this);
    }
    if (rc != NO_ERROR) {
        LOGE("add snapshot stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }
    m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
    return rc;
}

/*===========================================================================
 * FUNCTION   : addZSLChannel
 *
 * DESCRIPTION: add a ZSL channel that contains a preview stream and
 *              a snapshot stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addZSLChannel()
{
    int32_t rc = NO_ERROR;
    QCameraPicChannel *pChannel = NULL;
    char value[PROPERTY_VALUE_MAX];
    bool raw_yuv = false;

    if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
        // if we had ZSL channel before, delete it first
        delete m_channels[QCAMERA_CH_TYPE_ZSL];
        m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
    pChannel = new QCameraPicChannel(handle,
                                     mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for ZSL channel");
        return NO_MEMORY;
    }

    // ZSL channel, init with bundle attr and cb
    mm_camera_channel_attr_t attr;
    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    if (mParameters.isSceneSelectionEnabled()) {
        attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
    } else {
        attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
    }
    attr.look_back = mParameters.getZSLBackLookCount();
    attr.post_frame_skip = mParameters.getZSLBurstInterval();
    if (mParameters.isOEMFeatEnabled()) {
        LOGD("EDGE SMOOTH frameskip enabled");
        attr.post_frame_skip += mParameters.isOEMFeatFrameSkipEnabled();
    }
    attr.water_mark = mParameters.getZSLQueueDepth();
    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
    attr.user_expected_frame_id =
        mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;

    //Enabled matched queue
    if (isFrameSyncEnabled()) {
        LOGH("Enabling frame sync for dual camera, camera Id: %d",
                 mCameraId);
        attr.enable_frame_sync = 1;
    }
    rc = pChannel->init(&attr,
                        zsl_channel_cb,
                        this);
    if (rc != 0) {
        LOGE("init ZSL channel failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    // meta data stream always coexists with preview if applicable
    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
            metadata_stream_cb_routine, this);
    if (rc != NO_ERROR) {
        LOGE("add metadata stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    if (isNoDisplayMode()) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                nodisplay_preview_stream_cb_routine, this);
    } else {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                preview_stream_cb_routine, this);
        if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
            pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
                    synchronous_stream_cb_routine);
        }
    }
    if (rc != NO_ERROR) {
        LOGE("add preview stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
            NULL, this);
    if (rc != NO_ERROR) {
        LOGE("add snapshot stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    if (!isSecureMode()) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
                NULL, this);
        if (rc != NO_ERROR) {
            LOGE("add Analysis stream failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    }

    property_get("persist.camera.raw_yuv", value, "0");
    raw_yuv = atoi(value) > 0 ? true : false;
    if (raw_yuv) {
        rc = addStreamToChannel(pChannel,
                                CAM_STREAM_TYPE_RAW,
                                preview_raw_stream_cb_routine,
                                this);
        if (rc != NO_ERROR) {
            LOGE("add raw stream failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    }

    m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
    return rc;
}

/*===========================================================================
 * FUNCTION   : addCaptureChannel
 *
 * DESCRIPTION: add a capture channel that contains a snapshot stream
 *              and a postview stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 * NOTE       : Add this channel for regular capture usecase.
 *              For Live snapshot usecase, use addSnapshotChannel.
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addCaptureChannel()
{
    int32_t rc = NO_ERROR;
    QCameraPicChannel *pChannel = NULL;
    char value[PROPERTY_VALUE_MAX];
    bool raw_yuv = false;

    if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
        delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
        m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
    pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for capture channel");
        return NO_MEMORY;
    }

    // Capture channel, only need snapshot and postview streams start together
    mm_camera_channel_attr_t attr;
    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    if ( mLongshotEnabled ) {
        attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
        attr.look_back = mParameters.getZSLBackLookCount();
        attr.water_mark = mParameters.getZSLQueueDepth();
    } else {
        attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
    }
    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();

    rc = pChannel->init(&attr,
                        capture_channel_cb_routine,
                        this);
    if (rc != NO_ERROR) {
        LOGE("init capture channel failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    // meta data stream always coexists with snapshot in regular capture case
    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
            metadata_stream_cb_routine, this);
    if (rc != NO_ERROR) {
        LOGE("add metadata stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    if (mLongshotEnabled) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                preview_stream_cb_routine, this);
        if (rc != NO_ERROR) {
            LOGE("add preview stream failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
        if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
            pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
                    synchronous_stream_cb_routine);
        }
    //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
    } else if (!mParameters.getQuadraCfa()) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
                                NULL, this);
        if (rc != NO_ERROR) {
            LOGE("add postview stream failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    }

    if (!mParameters.getofflineRAW()) {
        rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
                NULL, this);
        if (rc != NO_ERROR) {
            LOGE("add snapshot stream failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    }

    stream_cb_routine stream_cb = NULL;
    property_get("persist.camera.raw_yuv", value, "0");
    raw_yuv = atoi(value) > 0 ? true : false;

    if (raw_yuv) {
        stream_cb = snapshot_raw_stream_cb_routine;
    }

    if ((raw_yuv) || (mParameters.getofflineRAW())) {
        rc = addStreamToChannel(pChannel,
                CAM_STREAM_TYPE_RAW, stream_cb, this);
        if (rc != NO_ERROR) {
            LOGE("add raw stream failed, ret = %d", rc);
            delete pChannel;
            return rc;
        }
    }

    m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
    return rc;
}

/*===========================================================================
 * FUNCTION   : addMetaDataChannel
 *
 * DESCRIPTION: add a meta data channel that contains a metadata stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addMetaDataChannel()
{
    int32_t rc = NO_ERROR;
    QCameraChannel *pChannel = NULL;

    if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
        delete m_channels[QCAMERA_CH_TYPE_METADATA];
        m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for metadata channel");
        return NO_MEMORY;
    }

    rc = pChannel->init(NULL,
                        NULL,
                        NULL);
    if (rc != NO_ERROR) {
        LOGE("init metadata channel failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
            metadata_stream_cb_routine, this);
    if (rc != NO_ERROR) {
        LOGE("add metadata stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
    return rc;
}

/*===========================================================================
 * FUNCTION   : addCallbackChannel
 *
 * DESCRIPTION: add a callback channel that contains a callback stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addCallbackChannel()
{
    int32_t rc = NO_ERROR;
    QCameraChannel *pChannel = NULL;

    if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
        delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
        m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for callback channel");
        return NO_MEMORY;
    }

    rc = pChannel->init(NULL, NULL, this);
    if (rc != NO_ERROR) {
        LOGE("init callback channel failed, ret = %d",
                 rc);
        delete pChannel;
        return rc;
    }

    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
            callback_stream_cb_routine, this);
    if (rc != NO_ERROR) {
        LOGE("add callback stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
    return rc;
}


/*===========================================================================
 * FUNCTION   : addAnalysisChannel
 *
 * DESCRIPTION: add a analysis channel that contains a analysis stream
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addAnalysisChannel()
{
    int32_t rc = NO_ERROR;
    QCameraChannel *pChannel = NULL;

    if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
        delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
        m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
    }

    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for metadata channel");
        return NO_MEMORY;
    }

    rc = pChannel->init(NULL, NULL, this);
    if (rc != NO_ERROR) {
        LOGE("init Analysis channel failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
            NULL, this);
    if (rc != NO_ERROR) {
        LOGE("add Analysis stream failed, ret = %d", rc);
        delete pChannel;
        return rc;
    }

    m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
    return rc;
}


/*===========================================================================
 * FUNCTION   : getPPConfig
 *
 * DESCRIPTION: get Post processing configaration data
 *
 * PARAMETERS :
 * @pp config:  pp config structure pointer,
 * @curIndex:  current pp channel index
 * @multipass: Flag if multipass prcessing enabled.
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
        int8_t curIndex, bool multipass)
{
    int32_t rc = NO_ERROR;
    int32_t feature_set = 0;

    if (multipass) {
        LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
                mParameters.getReprocCount(), curIndex);
    }

    LOGH("Supported pproc feature mask = %llx",
            gCamCapability[mCameraId]->qcom_supported_feature_mask);
    cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
    int32_t zoomLevel = mParameters.getParmZoomLevel();
    uint32_t rotation = mParameters.getJpegRotation();
    int32_t effect = mParameters.getEffectValue();

    pp_config.cur_reproc_count = curIndex + 1;
    pp_config.total_reproc_count = mParameters.getReprocCount();

    //Checking what feature mask to enable
    if (curIndex == 0) {
        if (mParameters.getQuadraCfa()) {
            feature_set = 2;
        } else {
            feature_set = 0;
        }
    } else if (curIndex == 1) {
        if (mParameters.getQuadraCfa()) {
            feature_set = 0;
        } else {
            feature_set = 1;
        }
    }

    switch(feature_set) {
        case 0:
            //Configure feature mask for first pass of reprocessing
            //check if any effects are enabled
            if ((CAM_EFFECT_MODE_OFF != effect) &&
                (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
                pp_config.effect = effect;
            }

            //check for features that need to be enabled by default like sharpness
            //(if supported by hw).
            if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
                !mParameters.isOptiZoomEnabled()) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
                pp_config.sharpness = mParameters.getSharpness();
            }

            //check if zoom is enabled
            if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
            }

            if (mParameters.isWNREnabled() &&
                (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
                pp_config.denoise2d.denoise_enable = 1;
                pp_config.denoise2d.process_plates =
                        mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
            }

            if (isCACEnabled()) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
            }

            //check if rotation is required
            if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
                if (rotation == 0) {
                    pp_config.rotation = ROTATE_0;
                } else if (rotation == 90) {
                    pp_config.rotation = ROTATE_90;
                } else if (rotation == 180) {
                    pp_config.rotation = ROTATE_180;
                } else if (rotation == 270) {
                    pp_config.rotation = ROTATE_270;
                }
            }

            if (mParameters.isHDREnabled()){
                pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
                pp_config.hdr_param.hdr_enable = 1;
                pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
                pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
            } else {
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
                pp_config.hdr_param.hdr_enable = 0;
            }

            //check if scaling is enabled
            if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
                mParameters.isReprocScaleEnabled() &&
                mParameters.isUnderReprocScaling()){
                pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
                mParameters.getPicSizeFromAPK(
                        pp_config.scale_param.output_width,
                        pp_config.scale_param.output_height);
            }

            if(mParameters.isUbiFocusEnabled()) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
            } else {
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
            }

            if(mParameters.isUbiRefocus()) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
                pp_config.misc_buf_param.misc_buffer_index = 0;
            } else {
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
            }

            if(mParameters.isChromaFlashEnabled()) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
                pp_config.flash_value = CAM_FLASH_ON;
            } else {
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
            }

            if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
                pp_config.zoom_level = (uint8_t) zoomLevel;
            } else {
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
            }

            if (mParameters.getofflineRAW()) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
            }

            if (mParameters.isTruePortraitEnabled()) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
                pp_config.misc_buf_param.misc_buffer_index = 0;
            } else {
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
            }

            if(mParameters.isStillMoreEnabled()) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
            } else {
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
            }

            if (mParameters.isOEMFeatEnabled()) {
                pp_config.feature_mask |= CAM_OEM_FEATURE_1;
            }

            if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
                if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
                    pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
                } else {
                    pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
                }
            }

            if ((multipass) &&
                    (m_postprocessor.getPPChannelCount() > 1)
                    && (!mParameters.getQuadraCfa())) {
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
                pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
                pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
            } else {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
            }

            cam_dimension_t thumb_src_dim;
            cam_dimension_t thumb_dst_dim;
            mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
            mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
            if ((thumb_dst_dim.width != thumb_src_dim.width) ||
                    (thumb_dst_dim.height != thumb_src_dim.height)) {
                if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
                    pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
                }
            }

            break;

        case 1:
            //Configure feature mask for second pass of reprocessing
            pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
            if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
                pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
                if (rotation == 0) {
                    pp_config.rotation = ROTATE_0;
                } else if (rotation == 90) {
                    pp_config.rotation = ROTATE_90;
                } else if (rotation == 180) {
                    pp_config.rotation = ROTATE_180;
                } else if (rotation == 270) {
                    pp_config.rotation = ROTATE_270;
                }
            }
            if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
                if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
                    pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
                } else {
                    pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
                }
            }
            pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
            pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
            pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_BYPASS;
            break;

        case 2:
            //Setting feature for Quadra CFA
            pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
            break;

    }

    LOGH("pproc feature mask set = %llx pass count = %d",
        pp_config.feature_mask, curIndex);
    return rc;
}

/*===========================================================================
 * FUNCTION   : addReprocChannel
 *
 * DESCRIPTION: add a reprocess channel that will do reprocess on frames
 *              coming from input channel
 *
 * PARAMETERS :
 *   @pInputChannel : ptr to input channel whose frames will be post-processed
 *   @cur_channel_index : Current channel index in multipass
 *
 * RETURN     : Ptr to the newly created channel obj. NULL if failed.
 *==========================================================================*/
QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
        QCameraChannel *pInputChannel, int8_t cur_channel_index)
{
    int32_t rc = NO_ERROR;
    QCameraReprocessChannel *pChannel = NULL;
    uint32_t burst_cnt = mParameters.getNumOfSnapshots();
    uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);

    if (pInputChannel == NULL) {
        LOGE("input channel obj is NULL");
        return NULL;
    }

    pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for reprocess channel");
        return NULL;
    }

    // Capture channel, only need snapshot and postview streams start together
    mm_camera_channel_attr_t attr;
    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
    attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
    rc = pChannel->init(&attr,
                        postproc_channel_cb_routine,
                        this);
    if (rc != NO_ERROR) {
        LOGE("init reprocess channel failed, ret = %d", rc);
        delete pChannel;
        return NULL;
    }

    // pp feature config
    cam_pp_feature_config_t pp_config;
    memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));

    rc = getPPConfig(pp_config, cur_channel_index,
            ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
    if (rc != NO_ERROR){
        LOGE("Error while creating PP config");
        delete pChannel;
        return NULL;
    }

    uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);

    //WNR and HDR happen inline. No extra buffers needed.
    cam_feature_mask_t temp_feature_mask = pp_config.feature_mask;
    temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
    if (temp_feature_mask && mParameters.isHDREnabled()) {
        minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
    }

    if (mParameters.isStillMoreEnabled()) {
        cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
        pp_config.burst_cnt = stillmore_config.burst_count;
        LOGH("Stillmore burst %d", pp_config.burst_cnt);

        // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
        // number of capture is already added. In the case of liveshot,
        // stillmore burst is 1. This is to account for the premature decrement
        if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
            minStreamBufNum += 1;
        }
    }

    if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
        minStreamBufNum += mParameters.getReprocCount() - 1;
        burst_cnt = mParameters.getReprocCount();
        if (cur_channel_index == 0) {
            pChannel->setReprocCount(2);
        } else {
            pChannel->setReprocCount(1);
        }
    } else {
        pChannel->setReprocCount(1);
    }

    if (isDualCamera() && mBundledSnapshot) {
        minStreamBufNum += 1;
    }

    // Add non inplace image lib buffers only when ppproc is present,
    // becuase pproc is non inplace and input buffers for img lib
    // are output for pproc and this number of extra buffers is required
    // If pproc is not there, input buffers for imglib are from snapshot stream
    uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
    if (temp_feature_mask && imglib_extra_bufs) {
        // 1 is added because getNumOfExtraBuffersForImageProc returns extra
        // buffers assuming number of capture is already added
        minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
    }

    //Mask out features that are already processed in snapshot stream.
    cam_feature_mask_t snapshot_feature_mask = 0;
    mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);

    pp_config.feature_mask &= ~snapshot_feature_mask;
    LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
            snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);

    bool offlineReproc = needOfflineReprocessing();
    if (m_postprocessor.mOfflineDataBufs != NULL) {
        offlineReproc = TRUE;
    }

    cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
    paddingInfo.offset_info.offset_x = 0;
    paddingInfo.offset_info.offset_y = 0;
    rc = pChannel->addReprocStreamsFromSource(*this,
                                              pp_config,
                                              pInputChannel,
                                              minStreamBufNum,
                                              burst_cnt,
                                              &paddingInfo,
                                              mParameters,
                                              mLongshotEnabled,
                                              offlineReproc);
    if (rc != NO_ERROR) {
        delete pChannel;
        return NULL;
    }

    return pChannel;
}

/*===========================================================================
 * FUNCTION   : addOfflineReprocChannel
 *
 * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
 *              that will do reprocess on frames coming from external images
 *
 * PARAMETERS :
 *   @img_config  : offline reporcess image info
 *   @pp_feature  : pp feature config
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
                                            cam_pp_offline_src_config_t &img_config,
                                            cam_pp_feature_config_t &pp_feature,
                                            stream_cb_routine stream_cb,
                                            void *userdata)
{
    int32_t rc = NO_ERROR;
    QCameraReprocessChannel *pChannel = NULL;

    pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
                                           mCameraHandle->ops);
    if (NULL == pChannel) {
        LOGE("no mem for reprocess channel");
        return NULL;
    }

    rc = pChannel->init(NULL, NULL, NULL);
    if (rc != NO_ERROR) {
        LOGE("init reprocess channel failed, ret = %d", rc);
        delete pChannel;
        return NULL;
    }

    QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
    if (pStreamInfo == NULL) {
        LOGE("no mem for stream info buf");
        delete pChannel;
        return NULL;
    }

    cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
    memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
    streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
    streamInfoBuf->fmt = img_config.input_fmt;
    streamInfoBuf->dim = img_config.input_dim;
    streamInfoBuf->buf_planes = img_config.input_buf_planes;
    streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
    streamInfoBuf->num_of_burst = img_config.num_of_bufs;

    streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
    streamInfoBuf->reprocess_config.offline = img_config;
    streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
    streamInfoBuf->num_bufs = img_config.num_of_bufs;

    rc = pChannel->addStream(*this,
            pStreamInfo, NULL,
            &gCamCapability[mCameraId]->padding_info,
            stream_cb, userdata, false);

    if (rc != NO_ERROR) {
        LOGE("add reprocess stream failed, ret = %d", rc);
        delete pChannel;
        return NULL;
    }

    return pChannel;
}

/*===========================================================================
 * FUNCTION   : addChannel
 *
 * DESCRIPTION: add a channel by its type
 *
 * PARAMETERS :
 *   @ch_type : channel type
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
{
    int32_t rc = UNKNOWN_ERROR;
    switch (ch_type) {
    case QCAMERA_CH_TYPE_ZSL:
        rc = addZSLChannel();
        break;
    case QCAMERA_CH_TYPE_CAPTURE:
        rc = addCaptureChannel();
        break;
    case QCAMERA_CH_TYPE_PREVIEW:
        rc = addPreviewChannel();
        break;
    case QCAMERA_CH_TYPE_VIDEO:
        rc = addVideoChannel();
        break;
    case QCAMERA_CH_TYPE_SNAPSHOT:
        rc = addSnapshotChannel();
        break;
    case QCAMERA_CH_TYPE_RAW:
        rc = addRawChannel();
        break;
    case QCAMERA_CH_TYPE_METADATA:
        rc = addMetaDataChannel();
        break;
    case QCAMERA_CH_TYPE_CALLBACK:
        rc = addCallbackChannel();
        break;
    case QCAMERA_CH_TYPE_ANALYSIS:
        rc = addAnalysisChannel();
        break;
    default:
        break;
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : delChannel
 *
 * DESCRIPTION: delete a channel by its type
 *
 * PARAMETERS :
 *   @ch_type : channel type
 *   @destroy : delete context as well
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
                                              bool destroy)
{
    if (m_channels[ch_type] != NULL) {
        if (destroy) {
            delete m_channels[ch_type];
            m_channels[ch_type] = NULL;
        } else {
            m_channels[ch_type]->deleteChannel();
        }
    }

    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : startChannel
 *
 * DESCRIPTION: start a channel by its type
 *
 * PARAMETERS :
 *   @ch_type : channel type
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
{
    int32_t rc = UNKNOWN_ERROR;
    if (m_channels[ch_type] != NULL) {
        rc = m_channels[ch_type]->start();
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : stopChannel
 *
 * DESCRIPTION: stop a channel by its type
 *
 * PARAMETERS :
 *   @ch_type : channel type
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
{
    int32_t rc = UNKNOWN_ERROR;
    if (m_channels[ch_type] != NULL) {
        rc = m_channels[ch_type]->stop();
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : preparePreview
 *
 * DESCRIPTION: add channels needed for preview
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::preparePreview()
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPAREPREVIEW);
    int32_t rc = NO_ERROR;

    LOGI("E");
    rc = mParameters.setStreamConfigure(false, false, false);
    if (rc != NO_ERROR) {
        LOGE("setStreamConfigure failed %d", rc);
        return rc;
    }

    //Trigger deferred job second camera
    if (isDualCamera()) {
        mParameters.setDeferCamera(CAM_DEFER_START);
    }

    if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
        rc = addChannel(QCAMERA_CH_TYPE_ZSL);
        if (rc != NO_ERROR) {
            LOGE("failed!! rc = %d", rc);
            return rc;
        }

        if (mParameters.isUBWCEnabled()) {
            cam_format_t fmt;
            mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
            if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
                rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
                if (rc != NO_ERROR) {
                    delChannel(QCAMERA_CH_TYPE_ZSL);
                    LOGE("failed!! rc = %d", rc);
                    return rc;
                }
            }
        }

        if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) {
            addChannel(QCAMERA_CH_TYPE_RAW);
        }
    } else if(isSecureMode()) {
        if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
            rc = addChannel(QCAMERA_CH_TYPE_RAW);
        } else {
            rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
        }
    } else {
        bool recordingHint = mParameters.getRecordingHintValue();
        if(!isRdiMode() && recordingHint) {
            //stop face detection,longshot,etc if turned ON in Camera mode
#ifndef VANILLA_HAL
            int32_t arg; //dummy arg
            if (isLongshotEnabled()) {
                sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
            }
            if (mParameters.isFaceDetectionEnabled()
                    && (!mParameters.fdModeInVideo())) {
                sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
            }
            if (mParameters.isHistogramEnabled()) {
                sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
            }
#endif
            //Don't create snapshot channel for liveshot, if low power mode is set.
            //Use video stream instead.
            if (!isLowPowerMode()) {
               rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
               if (rc != NO_ERROR) {
                   return rc;
               }
            }

            rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
            if (rc != NO_ERROR) {
                delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
                LOGE("failed!! rc = %d", rc);
                return rc;
            }
        }

        rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
        if (!isRdiMode() && (rc != NO_ERROR)) {
            if (recordingHint) {
                delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
                delChannel(QCAMERA_CH_TYPE_VIDEO);
            }
        }

        if (mParameters.isUBWCEnabled() && !recordingHint) {
            cam_format_t fmt;
            mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
            if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
                rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
                if (rc != NO_ERROR) {
                    delChannel(QCAMERA_CH_TYPE_PREVIEW);
                    if (!isRdiMode()) {
                        delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
                        delChannel(QCAMERA_CH_TYPE_VIDEO);
                    }
                    LOGE("failed!! rc = %d", rc);
                    return rc;
                }
            }
        }

        if (NO_ERROR != rc) {
            delChannel(QCAMERA_CH_TYPE_PREVIEW);
            LOGE("failed!! rc = %d", rc);
        }
    }

    if ((rc != NO_ERROR) && (isDualCamera())) {
        mParameters.setDeferCamera(CAM_DEFER_FLUSH);
    }

    LOGI("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : unpreparePreview
 *
 * DESCRIPTION: delete channels for preview
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::unpreparePreview()
{
    if (isDualCamera()) {
        mParameters.setDeferCamera(CAM_DEFER_FLUSH);
    }
    delChannel(QCAMERA_CH_TYPE_ZSL);
    delChannel(QCAMERA_CH_TYPE_PREVIEW);
    delChannel(QCAMERA_CH_TYPE_VIDEO);
    delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
    delChannel(QCAMERA_CH_TYPE_CALLBACK);
    delChannel(QCAMERA_CH_TYPE_RAW);
}

/*===========================================================================
 * FUNCTION   : playShutter
 *
 * DESCRIPTION: send request to play shutter sound
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::playShutter(){
     if (mNotifyCb == NULL ||
         msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
         LOGD("shutter msg not enabled or NULL cb");
         return;
     }
     LOGH("CAMERA_MSG_SHUTTER ");
     qcamera_callback_argm_t cbArg;
     memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
     cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
     cbArg.msg_type = CAMERA_MSG_SHUTTER;
     cbArg.ext1 = 0;
     cbArg.ext2 = false;
     m_cbNotifier.notifyCallback(cbArg);
}

/*===========================================================================
 * FUNCTION   : getChannelByHandle
 *
 * DESCRIPTION: return a channel by its handle
 *
 * PARAMETERS :
 *   @channelHandle : channel handle
 *
 * RETURN     : a channel obj if found, NULL if not found
 *==========================================================================*/
QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
{
    for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
        if (m_channels[i] != NULL &&
            (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
            return m_channels[i];
        }
    }

    return NULL;
}
/*===========================================================================
 * FUNCTION   : needPreviewFDCallback
 *
 * DESCRIPTION: decides if needPreviewFDCallback
 *
 * PARAMETERS :
 *   @num_faces : number of faces
 *
 * RETURN     : bool type of status
 *              true  -- success
 *              fale -- failure code
 *==========================================================================*/
bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
{
    if (num_faces == 0 && mNumPreviewFaces == 0) {
        return false;
    }

    return true;
}

/*===========================================================================
 * FUNCTION   : processFaceDetectionReuslt
 *
 * DESCRIPTION: process face detection reuslt
 *
 * PARAMETERS :
 *   @faces_data : ptr to face processing result struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
{
    if (!mParameters.isFaceDetectionEnabled()) {
        LOGH("FaceDetection not enabled, no ops here");
        return NO_ERROR;
    }

    qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
    cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
    if ((NULL == mDataCb) ||
        (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
        (!needPreviewFDCallback(detect_data->num_faces_detected))
#ifndef VANILLA_HAL
        || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
#endif
        ) {
        LOGH("metadata msgtype not enabled, no ops here");
        return NO_ERROR;
    }

    if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
        // Don't send callback to app if this is skipped by fd at backend
        return NO_ERROR;
    }

    cam_dimension_t display_dim;
    mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
    if (display_dim.width <= 0 || display_dim.height <= 0) {
        LOGE("Invalid preview width or height (%d x %d)",
               display_dim.width, display_dim.height);
        return UNKNOWN_ERROR;
    }

    // process face detection result
    // need separate face detection in preview or snapshot type
    size_t faceResultSize = 0;
    size_t data_len = 0;
    if(fd_type == QCAMERA_FD_PREVIEW){
        //fd for preview frames
        faceResultSize = sizeof(camera_frame_metadata_t);
        faceResultSize += sizeof(camera_face_t) * MAX_ROI;
    }else if(fd_type == QCAMERA_FD_SNAPSHOT){
#ifndef VANILLA_HAL
        // fd for snapshot frames
        //check if face is detected in this frame
        if(detect_data->num_faces_detected > 0){
            data_len = sizeof(camera_frame_metadata_t) +
                    sizeof(camera_face_t) * detect_data->num_faces_detected;
        }else{
            //no face
            data_len = 0;
        }
#endif
        faceResultSize = 1 *sizeof(int)    //meta data type
                       + 1 *sizeof(int)    // meta data len
                       + data_len;         //data
    }

    camera_memory_t *faceResultBuffer = mGetMemory(-1,
                                                   faceResultSize,
                                                   1,
                                                   mCallbackCookie);
    if ( NULL == faceResultBuffer ) {
        LOGE("Not enough memory for face result data");
        return NO_MEMORY;
    }

    unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
    memset(pFaceResult, 0, faceResultSize);
    unsigned char *faceData = NULL;
    if(fd_type == QCAMERA_FD_PREVIEW){
        faceData = pFaceResult;
        mNumPreviewFaces = detect_data->num_faces_detected;
    }else if(fd_type == QCAMERA_FD_SNAPSHOT){
#ifndef VANILLA_HAL
        //need fill meta type and meta data len first
        int *data_header = (int* )pFaceResult;
        data_header[0] = CAMERA_META_DATA_FD;
        data_header[1] = (int)data_len;

        if(data_len <= 0){
            //if face is not valid or do not have face, return
            qcamera_callback_argm_t cbArg;
            memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
            cbArg.cb_type = QCAMERA_DATA_CALLBACK;
            cbArg.msg_type = CAMERA_MSG_META_DATA;
            cbArg.data = faceResultBuffer;
            cbArg.user_data = faceResultBuffer;
            cbArg.cookie = this;
            cbArg.release_cb = releaseCameraMemory;
            int32_t rc = m_cbNotifier.notifyCallback(cbArg);
            if (rc != NO_ERROR) {
                LOGE("fail sending notification");
                faceResultBuffer->release(faceResultBuffer);
            }
            return rc;
        }
#endif
        faceData = pFaceResult + 2 *sizeof(int); //skip two int length
    }

    camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
    camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );

    roiData->number_of_faces = detect_data->num_faces_detected;
    roiData->faces = faces;
    LOGL("FD_DEBUG : Frame[%d] : number_of_faces=%d, display_dim=%d %d",
            detect_data->frame_id, detect_data->num_faces_detected,
            display_dim.width, display_dim.height);
    if (roiData->number_of_faces > 0) {
        for (int i = 0; i < roiData->number_of_faces; i++) {
            faces[i].id = detect_data->faces[i].face_id;
            faces[i].score = detect_data->faces[i].score;

            // left
            faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
                    detect_data->faces[i].face_boundary.left,
                    display_dim.width, 2000, -1000);

            // top
            faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
                    detect_data->faces[i].face_boundary.top,
                    display_dim.height, 2000, -1000);

            // right
            faces[i].rect[2] = faces[i].rect[0] +
                    MAP_TO_DRIVER_COORDINATE(
                    detect_data->faces[i].face_boundary.width,
                    display_dim.width, 2000, 0);

             // bottom
            faces[i].rect[3] = faces[i].rect[1] +
                    MAP_TO_DRIVER_COORDINATE(
                    detect_data->faces[i].face_boundary.height,
                    display_dim.height, 2000, 0);

            LOGL("FD_DEBUG : Frame[%d] : Face[%d] : id=%d, score=%d, "
                    "CAM[left=%d, top=%d, w=%d, h=%d], "
                    "APP[left=%d, top=%d, right=%d, bottom=%d] ",
                    detect_data->frame_id, i, faces[i].id, faces[i].score,
                    detect_data->faces[i].face_boundary.left,
                    detect_data->faces[i].face_boundary.top,
                    detect_data->faces[i].face_boundary.width,
                    detect_data->faces[i].face_boundary.height,
                    faces[i].rect[0], faces[i].rect[1],
                    faces[i].rect[2], faces[i].rect[3]);

            if (faces_data->landmark_valid) {
                // Center of left eye
                if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) {
                    faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
                            faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
                            display_dim.width, 2000, -1000);
                    faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
                            faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
                            display_dim.height, 2000, -1000);
                } else {
                    faces[i].left_eye[0] = FACE_INVALID_POINT;
                    faces[i].left_eye[1] = FACE_INVALID_POINT;
                }

                // Center of right eye
                if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) {
                    faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
                            faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
                            display_dim.width, 2000, -1000);
                    faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
                            faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
                            display_dim.height, 2000, -1000);
                } else {
                    faces[i].right_eye[0] = FACE_INVALID_POINT;
                    faces[i].right_eye[1] = FACE_INVALID_POINT;
                }

                // Center of mouth
                if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) {
                    faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
                            faces_data->landmark_data.face_landmarks[i].mouth_center.x,
                            display_dim.width, 2000, -1000);
                    faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
                            faces_data->landmark_data.face_landmarks[i].mouth_center.y,
                            display_dim.height, 2000, -1000);
                } else {
                    faces[i].mouth[0] = FACE_INVALID_POINT;
                    faces[i].mouth[1] = FACE_INVALID_POINT;
                }

                LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
                        "eye : left(%d, %d) right(%d, %d), mouth(%d, %d)",
                        detect_data->frame_id, i, faces[i].left_eye[0], faces[i].left_eye[1],
                        faces[i].right_eye[0], faces[i].right_eye[1],
                        faces[i].mouth[0], faces[i].mouth[1]);
            } else {
                // return -2000 if invalid
                faces[i].left_eye[0] = FACE_INVALID_POINT;
                faces[i].left_eye[1] = FACE_INVALID_POINT;

                faces[i].right_eye[0] = FACE_INVALID_POINT;
                faces[i].right_eye[1] = FACE_INVALID_POINT;

                faces[i].mouth[0] = FACE_INVALID_POINT;
                faces[i].mouth[1] = FACE_INVALID_POINT;
            }

#ifndef VANILLA_HAL
#ifdef TARGET_TS_MAKEUP
            mFaceRect.left = detect_data->faces[i].face_boundary.left;
            mFaceRect.top = detect_data->faces[i].face_boundary.top;
            mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
            mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
#endif
            if (faces_data->smile_valid) {
                faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
                faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;

                LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : smile_degree=%d, smile_score=%d",
                        detect_data->frame_id, i, faces[i].smile_degree, faces[i].smile_score);
            }
            if (faces_data->blink_valid) {
                faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
                faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
                faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;

                LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
                        "blink_detected=%d, leye_blink=%d, reye_blink=%d",
                        detect_data->frame_id, i, faces[i].blink_detected, faces[i].leye_blink,
                        faces[i].reye_blink);
            }
            if (faces_data->recog_valid) {
                faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;

                LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : face_recognised=%d",
                        detect_data->frame_id, i, faces[i].face_recognised);
            }
            if (faces_data->gaze_valid) {
                faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
                faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
                faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
                faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
                faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
                faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;

                LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : gaze_angle=%d, updown_dir=%d, "
                        "leftright_dir=%d,, roll_dir=%d, left_right_gaze=%d, top_bottom_gaze=%d",
                        detect_data->frame_id, i, faces[i].gaze_angle, faces[i].updown_dir,
                        faces[i].leftright_dir, faces[i].roll_dir, faces[i].left_right_gaze,
                        faces[i].top_bottom_gaze);
            }
#endif

        }
    }
    else{
#ifdef TARGET_TS_MAKEUP
        memset(&mFaceRect,-1,sizeof(mFaceRect));
#endif
    }
    qcamera_callback_argm_t cbArg;
    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
    cbArg.cb_type = QCAMERA_DATA_CALLBACK;
    if(fd_type == QCAMERA_FD_PREVIEW){
        cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
    }
#ifndef VANILLA_HAL
    else if(fd_type == QCAMERA_FD_SNAPSHOT){
        cbArg.msg_type = CAMERA_MSG_META_DATA;
    }
#endif
    cbArg.data = faceResultBuffer;
    cbArg.metadata = roiData;
    cbArg.user_data = faceResultBuffer;
    cbArg.cookie = this;
    cbArg.release_cb = releaseCameraMemory;
    int32_t rc = m_cbNotifier.notifyCallback(cbArg);
    if (rc != NO_ERROR) {
        LOGE("fail sending notification");
        faceResultBuffer->release(faceResultBuffer);
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : releaseCameraMemory
 *
 * DESCRIPTION: releases camera memory objects
 *
 * PARAMETERS :
 *   @data    : buffer to be released
 *   @cookie  : context data
 *   @cbStatus: callback status
 *
 * RETURN     : None
 *==========================================================================*/
void QCamera2HardwareInterface::releaseCameraMemory(void *data,
                                                    void */*cookie*/,
                                                    int32_t /*cbStatus*/)
{
    camera_memory_t *mem = ( camera_memory_t * ) data;
    if ( NULL != mem ) {
        mem->release(mem);
    }
}

/*===========================================================================
 * FUNCTION   : returnStreamBuffer
 *
 * DESCRIPTION: returns back a stream buffer
 *
 * PARAMETERS :
 *   @data    : buffer to be released
 *   @cookie  : context data
 *   @cbStatus: callback status
 *
 * RETURN     : None
 *==========================================================================*/
void QCamera2HardwareInterface::returnStreamBuffer(void *data,
                                                   void *cookie,
                                                   int32_t /*cbStatus*/)
{
    QCameraStream *stream = ( QCameraStream * ) cookie;
    int idx = *((int *)data);
    if ((NULL != stream) && (0 <= idx)) {
        stream->bufDone((uint32_t)idx);
    } else {
        LOGE("Cannot return buffer %d %p", idx, cookie);
    }
}

/*===========================================================================
 * FUNCTION   : processHistogramStats
 *
 * DESCRIPTION: process histogram stats
 *
 * PARAMETERS :
 *   @hist_data : ptr to histogram stats struct
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::processHistogramStats(
        __unused cam_hist_stats_t &stats_data)
{
#ifndef VANILLA_HAL
    if (!mParameters.isHistogramEnabled()) {
        LOGH("Histogram not enabled, no ops here");
        return NO_ERROR;
    }

    camera_memory_t *histBuffer = mGetMemory(-1,
                                             sizeof(cam_histogram_data_t),
                                             1,
                                             mCallbackCookie);
    if ( NULL == histBuffer ) {
        LOGE("Not enough memory for histogram data");
        return NO_MEMORY;
    }

    cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
    if (pHistData == NULL) {
        LOGE("memory data ptr is NULL");
        return UNKNOWN_ERROR;
    }

    switch (stats_data.type) {
    case CAM_HISTOGRAM_TYPE_BAYER:
        switch (stats_data.bayer_stats.data_type) {
            case CAM_STATS_CHANNEL_Y:
            case CAM_STATS_CHANNEL_R:
                *pHistData = stats_data.bayer_stats.r_stats;
                break;
            case CAM_STATS_CHANNEL_GR:
                *pHistData = stats_data.bayer_stats.gr_stats;
                break;
            case CAM_STATS_CHANNEL_GB:
            case CAM_STATS_CHANNEL_ALL:
                *pHistData = stats_data.bayer_stats.gb_stats;
                break;
            case CAM_STATS_CHANNEL_B:
                *pHistData = stats_data.bayer_stats.b_stats;
                break;
            default:
                *pHistData = stats_data.bayer_stats.r_stats;
                break;
        }
        break;
    case CAM_HISTOGRAM_TYPE_YUV:
        *pHistData = stats_data.yuv_stats;
        break;
    }

    qcamera_callback_argm_t cbArg;
    memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
    cbArg.cb_type = QCAMERA_DATA_CALLBACK;
    cbArg.msg_type = CAMERA_MSG_STATS_DATA;
    cbArg.data = histBuffer;
    cbArg.user_data = histBuffer;
    cbArg.cookie = this;
    cbArg.release_cb = releaseCameraMemory;
    int32_t rc = m_cbNotifier.notifyCallback(cbArg);
    if (rc != NO_ERROR) {
        LOGE("fail sending notification");
        histBuffer->release(histBuffer);
    }
#endif
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : calcThermalLevel
 *
 * DESCRIPTION: Calculates the target fps range depending on
 *              the thermal level.
 *              Note that this function can be called from QCameraParametersIntf
 *              while mutex is held. So it should not call back into
 *              QCameraParametersIntf causing deadlock.
 *
 * PARAMETERS :
 *   @level      : received thermal level
 *   @minFPS     : minimum configured fps range
 *   @maxFPS     : maximum configured fps range
 *   @minVideoFps: minimum configured fps range
 *   @maxVideoFps: maximum configured fps range
 *   @adjustedRange : target fps range
 *   @skipPattern : target skip pattern
 *   @bRecordingHint : recording hint value
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::calcThermalLevel(
            qcamera_thermal_level_enum_t level,
            const int minFPSi,
            const int maxFPSi,
            const float &minVideoFps,
            const float &maxVideoFps,
            cam_fps_range_t &adjustedRange,
            enum msm_vfe_frame_skip_pattern &skipPattern,
            bool bRecordingHint)
{
    const float minFPS = (float)minFPSi;
    const float maxFPS = (float)maxFPSi;

    LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
              "video minfps %f, video maxfpS %f",
             level, minFPS, maxFPS, minVideoFps, maxVideoFps);

    switch(level) {
    case QCAMERA_THERMAL_NO_ADJUSTMENT:
        {
            adjustedRange.min_fps = minFPS / 1000.0f;
            adjustedRange.max_fps = maxFPS / 1000.0f;
            adjustedRange.video_min_fps = minVideoFps / 1000.0f;
            adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
            skipPattern = NO_SKIP;
        }
        break;
    case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
        {
            adjustedRange.min_fps = minFPS / 1000.0f;
            adjustedRange.max_fps = maxFPS / 1000.0f;
            adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
            adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
            adjustedRange.video_min_fps = minVideoFps / 1000.0f;
            adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
            adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
            adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
            if ( adjustedRange.min_fps < 1 ) {
                adjustedRange.min_fps = 1;
            }
            if ( adjustedRange.max_fps < 1 ) {
                adjustedRange.max_fps = 1;
            }
            if ( adjustedRange.video_min_fps < 1 ) {
                adjustedRange.video_min_fps = 1;
            }
            if ( adjustedRange.video_max_fps < 1 ) {
                adjustedRange.video_max_fps = 1;
            }
            skipPattern = EVERY_2FRAME;
        }
        break;
    case QCAMERA_THERMAL_BIG_ADJUSTMENT:
        {
            adjustedRange.min_fps = minFPS / 1000.0f;
            adjustedRange.max_fps = maxFPS / 1000.0f;
            adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
            adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
            adjustedRange.video_min_fps = minVideoFps / 1000.0f;
            adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
            adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
            adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
            if ( adjustedRange.min_fps < 1 ) {
                adjustedRange.min_fps = 1;
            }
            if ( adjustedRange.max_fps < 1 ) {
                adjustedRange.max_fps = 1;
            }
            if ( adjustedRange.video_min_fps < 1 ) {
                adjustedRange.video_min_fps = 1;
            }
            if ( adjustedRange.video_max_fps < 1 ) {
                adjustedRange.video_max_fps = 1;
            }
            skipPattern = EVERY_4FRAME;
        }
        break;
    case QCAMERA_THERMAL_MAX_ADJUSTMENT:
        {
            // Stop Preview?
            // Set lowest min FPS for now
            adjustedRange.min_fps = minFPS/1000.0f;
            adjustedRange.max_fps = minFPS/1000.0f;
            cam_capability_t *capability = gCamCapability[mCameraId];
            for (size_t i = 0;
                     i < capability->fps_ranges_tbl_cnt;
                     i++) {
                if (capability->fps_ranges_tbl[i].min_fps <
                        adjustedRange.min_fps) {
                    adjustedRange.min_fps =
                            capability->fps_ranges_tbl[i].min_fps;
                    adjustedRange.max_fps = adjustedRange.min_fps;
                }
            }
            skipPattern = MAX_SKIP;
            adjustedRange.video_min_fps = adjustedRange.min_fps;
            adjustedRange.video_max_fps = adjustedRange.max_fps;
        }
        break;
    case QCAMERA_THERMAL_SHUTDOWN:
        {
            // send error notify
            LOGE("Received shutdown thermal level. Closing camera");
            sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
        }
        break;
    default:
        {
            LOGW("Invalid thermal level %d", level);
            return BAD_VALUE;
        }
        break;
    }
    if (level >= QCAMERA_THERMAL_NO_ADJUSTMENT && level <= QCAMERA_THERMAL_MAX_ADJUSTMENT) {
        if (bRecordingHint) {
            adjustedRange.min_fps = minFPS / 1000.0f;
            adjustedRange.max_fps = maxFPS / 1000.0f;
            adjustedRange.video_min_fps = minVideoFps / 1000.0f;
            adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
            skipPattern = NO_SKIP;
            LOGH("No FPS mitigation in camcorder mode");
        }
        LOGH("Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
                  level, adjustedRange.min_fps, adjustedRange.max_fps,
                    adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
    }

    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : recalcFPSRange
 *
 * DESCRIPTION: adjust the configured fps range regarding
 *              the last thermal level.
 *
 * PARAMETERS :
 *   @minFPS      : minimum configured fps range
 *   @maxFPS      : maximum configured fps range
 *   @minVideoFPS : minimum configured video fps
 *   @maxVideoFPS : maximum configured video fps
 *   @adjustedRange : target fps range
 *   @bRecordingHint : recording hint value
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
        const float &minVideoFPS, const float &maxVideoFPS,
        cam_fps_range_t &adjustedRange, bool bRecordingHint)
{
    enum msm_vfe_frame_skip_pattern skipPattern;
    calcThermalLevel(mThermalLevel,
                     minFPS,
                     maxFPS,
                     minVideoFPS,
                     maxVideoFPS,
                     adjustedRange,
                     skipPattern,
                     bRecordingHint);
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : updateThermalLevel
 *
 * DESCRIPTION: update thermal level depending on thermal events
 *
 * PARAMETERS :
 *   @level   : thermal level
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
{
    int ret = NO_ERROR;
    cam_fps_range_t adjustedRange;
    int minFPS, maxFPS;
    float minVideoFPS, maxVideoFPS;
    enum msm_vfe_frame_skip_pattern skipPattern;
    bool value;
    qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;


    if (!mCameraOpened) {
        LOGH("Camera is not opened, no need to update camera parameters");
        return NO_ERROR;
    }

    mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
    qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
    if (mParameters.isHfrMode()) {
        cam_fps_range_t hfrFpsRange;
        mParameters.getHfrFps(hfrFpsRange);
        minVideoFPS = hfrFpsRange.video_min_fps;
        maxVideoFPS = hfrFpsRange.video_max_fps;
    } else {
        minVideoFPS = minFPS;
        maxVideoFPS = maxFPS;
    }

    value = mParameters.getRecordingHintValue();
    calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
            adjustedRange, skipPattern, value );
    mThermalLevel = level;

    if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
        ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
    else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
        ret = mParameters.setFrameSkip(skipPattern);
    else
        LOGW("Incorrect thermal mode %d", thermalMode);

    return ret;

}

/*===========================================================================
 * FUNCTION   : updateParameters
 *
 * DESCRIPTION: update parameters
 *
 * PARAMETERS :
 *   @parms       : input parameters string
 *   @needRestart : output, flag to indicate if preview restart is needed
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
{
    int rc = NO_ERROR;

    String8 str = String8(parms);
    rc =  mParameters.updateParameters(str, needRestart);
    setNeedRestart(needRestart);

    // update stream based parameter settings
    for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
        if (m_channels[i] != NULL) {
            m_channels[i]->UpdateStreamBasedParameters(mParameters);
        }
    }

    return rc;
}

/*===========================================================================
 * FUNCTION   : commitParameterChanges
 *
 * DESCRIPTION: commit parameter changes to the backend to take effect
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 * NOTE       : This function must be called after updateParameters.
 *              Otherwise, no change will be passed to backend to take effect.
 *==========================================================================*/
int QCamera2HardwareInterface::commitParameterChanges()
{
    int rc = NO_ERROR;
    rc = mParameters.commitParameters();
    if (rc == NO_ERROR) {
        // update number of snapshot based on committed parameters setting
        rc = mParameters.setNumOfSnapshot();
    }

    if (isDualCamera() &&
        mParameters.isZoomChanged()) {
        // If zoom changes, get the updated FOV-control result and if needed send the dual
        // camera parameters to backend
        processDualCamFovControl();
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : needDebugFps
 *
 * DESCRIPTION: if fps log info need to be printed out
 *
 * PARAMETERS : none
 *
 * RETURN     : true: need print out fps log
 *              false: no need to print out fps log
 *==========================================================================*/
bool QCamera2HardwareInterface::needDebugFps()
{
    bool needFps = false;
    needFps = mParameters.isFpsDebugEnabled();
    return needFps;
}

/*===========================================================================
 * FUNCTION   : isCACEnabled
 *
 * DESCRIPTION: if CAC is enabled
 *
 * PARAMETERS : none
 *
 * RETURN     : true: needed
 *              false: no need
 *==========================================================================*/
bool QCamera2HardwareInterface::isCACEnabled()
{
    char prop[PROPERTY_VALUE_MAX];
    memset(prop, 0, sizeof(prop));
    property_get("persist.camera.feature.cac", prop, "0");
    int enableCAC = atoi(prop);
    return enableCAC == 1;
}

/*===========================================================================
 * FUNCTION   : is4k2kResolution
 *
 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
 *
 * PARAMETERS : none
 *
 * RETURN     : true: needed
 *              false: no need
 *==========================================================================*/
bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
{
   bool enabled = false;
   if ((resolution->width == 4096 && resolution->height == 2160) ||
       (resolution->width == 3840 && resolution->height == 2160) ) {
      enabled = true;
   }
   return enabled;
}

/*===========================================================================
 * FUNCTION   : isPreviewRestartEnabled
 *
 * DESCRIPTION: Check whether preview should be restarted automatically
 *              during image capture.
 *
 * PARAMETERS : none
 *
 * RETURN     : true: needed
 *              false: no need
 *==========================================================================*/
bool QCamera2HardwareInterface::isPreviewRestartEnabled()
{
    char prop[PROPERTY_VALUE_MAX];
    memset(prop, 0, sizeof(prop));
    property_get("persist.camera.feature.restart", prop, "0");
    int earlyRestart = atoi(prop);
    return earlyRestart == 1;
}

/*===========================================================================
 * FUNCTION   : needReprocess
 *
 * DESCRIPTION: if reprocess is needed
 *
 * PARAMETERS : none
 *
 * RETURN     : true: needed
 *              false: no need
 *==========================================================================*/
bool QCamera2HardwareInterface::needReprocess()
{
    bool needReprocess = false;

    if (!mParameters.isJpegPictureFormat() &&
        !mParameters.isNV21PictureFormat()) {
        // RAW image, no need to reprocess
        return false;
    }

    //Disable reprocess for small jpeg size or 4K liveshot case but enable if lowpower mode
    if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
            && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
        return false;
    }

    // pp feature config
    cam_pp_feature_config_t pp_config;
    memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));

    //Decide whether to do reprocess or not based on
    //ppconfig obtained in the first pass.
    getPPConfig(pp_config);

    if (pp_config.feature_mask > 0) {
        needReprocess = true;
    }

    LOGH("needReprocess %s", needReprocess ? "true" : "false");
    return needReprocess;
}


/*===========================================================================
 * FUNCTION   : needRotationReprocess
 *
 * DESCRIPTION: if rotation needs to be done by reprocess in pp
 *
 * PARAMETERS : none
 *
 * RETURN     : true: needed
 *              false: no need
 *==========================================================================*/
bool QCamera2HardwareInterface::needRotationReprocess()
{
    if (!mParameters.isJpegPictureFormat() &&
        !mParameters.isNV21PictureFormat()) {
        // RAW image, no need to reprocess
        return false;
    }

    //Disable reprocess for 4K liveshot case
    if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
            && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
        //Disable reprocess for 4K liveshot case or small jpeg size
         return false;
    }

    if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
            CAM_QCOM_FEATURE_ROTATION) > 0 &&
            (mParameters.getJpegRotation() > 0)) {
        // current rotation is not zero, and pp has the capability to process rotation
        LOGH("need to do reprocess for rotation=%d",
                 mParameters.getJpegRotation());
        return true;
    }

    return false;
}

/*===========================================================================
 * FUNCTION   : getThumbnailSize
 *
 * DESCRIPTION: get user set thumbnail size
 *
 * PARAMETERS :
 *   @dim     : output of thumbnail dimension
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
{
    mParameters.getThumbnailSize(&dim.width, &dim.height);
}

/*===========================================================================
 * FUNCTION   : getJpegQuality
 *
 * DESCRIPTION: get user set jpeg quality
 *
 * PARAMETERS : none
 *
 * RETURN     : jpeg quality setting
 *==========================================================================*/
uint32_t QCamera2HardwareInterface::getJpegQuality()
{
    uint32_t quality = 0;
    quality =  mParameters.getJpegQuality();
    return quality;
}

/*===========================================================================
 * FUNCTION   : getExifData
 *
 * DESCRIPTION: get exif data to be passed into jpeg encoding
 *
 * PARAMETERS : none
 *
 * RETURN     : exif data from user setting and GPS
 *==========================================================================*/
QCameraExif *QCamera2HardwareInterface::getExifData()
{
    QCameraExif *exif = new QCameraExif();
    if (exif == NULL) {
        LOGE("No memory for QCameraExif");
        return NULL;
    }

    int32_t rc = NO_ERROR;

    // add exif entries
    String8 dateTime, subSecTime;
    rc = mParameters.getExifDateTime(dateTime, subSecTime);
    if(rc == NO_ERROR) {
        exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
                (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
        exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
                (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
        exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
                (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
        exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
                (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
        exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
                (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
        exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
                (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
    } else {
        LOGW("getExifDateTime failed");
    }

    rat_t focalLength;
    rc = mParameters.getExifFocalLength(&focalLength);
    if (rc == NO_ERROR) {
        exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
                       EXIF_RATIONAL,
                       1,
                       (void *)&(focalLength));
    } else {
        LOGW("getExifFocalLength failed");
    }

    uint16_t isoSpeed = mParameters.getExifIsoSpeed();
    if (getSensorType() != CAM_SENSOR_YUV) {
        exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
                       EXIF_SHORT,
                       1,
                       (void *)&(isoSpeed));
    }

    char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
    uint32_t count = 0;

    /*gps data might not be available */
    rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
    if(rc == NO_ERROR) {
        exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
                       EXIF_ASCII,
                       count,
                       (void *)gpsProcessingMethod);
    } else {
        LOGW("getExifGpsProcessingMethod failed");
    }

    rat_t latitude[3];
    char latRef[2];
    rc = mParameters.getExifLatitude(latitude, latRef);
    if(rc == NO_ERROR) {
        exif->addEntry(EXIFTAGID_GPS_LATITUDE,
                       EXIF_RATIONAL,
                       3,
                       (void *)latitude);
        exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
                       EXIF_ASCII,
                       2,
                       (void *)latRef);
    } else {
        LOGW("getExifLatitude failed");
    }

    rat_t longitude[3];
    char lonRef[2];
    rc = mParameters.getExifLongitude(longitude, lonRef);
    if(rc == NO_ERROR) {
        exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
                       EXIF_RATIONAL,
                       3,
                       (void *)longitude);

        exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
                       EXIF_ASCII,
                       2,
                       (void *)lonRef);
    } else {
        LOGW("getExifLongitude failed");
    }

    rat_t altitude;
    char altRef;
    rc = mParameters.getExifAltitude(&altitude, &altRef);
    if(rc == NO_ERROR) {
        exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
                       EXIF_RATIONAL,
                       1,
                       (void *)&(altitude));

        exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
                       EXIF_BYTE,
                       1,
                       (void *)&altRef);
    } else {
        LOGW("getExifAltitude failed");
    }

    char gpsDateStamp[20];
    rat_t gpsTimeStamp[3];
    rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
    if(rc == NO_ERROR) {
        exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
                       EXIF_ASCII,
                       (uint32_t)(strlen(gpsDateStamp) + 1),
                       (void *)gpsDateStamp);

        exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
                       EXIF_RATIONAL,
                       3,
                       (void *)gpsTimeStamp);
    } else {
        LOGW("getExifGpsDataTimeStamp failed");
    }

#ifdef ENABLE_MODEL_INFO_EXIF

    char value[PROPERTY_VALUE_MAX];
    if (property_get("persist.sys.exif.make", value, "") > 0 ||
            property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
        exif->addEntry(EXIFTAGID_MAKE,
                EXIF_ASCII, strlen(value) + 1, (void *)value);
    } else {
        LOGW("getExifMaker failed");
    }

    if (property_get("persist.sys.exif.model", value, "") > 0 ||
            property_get("ro.product.model", value, "QCAM-AA") > 0) {
        exif->addEntry(EXIFTAGID_MODEL,
                EXIF_ASCII, strlen(value) + 1, (void *)value);
    } else {
        LOGW("getExifModel failed");
    }

    if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
        exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
                (uint32_t)(strlen(value) + 1), (void *)value);
    } else {
        LOGW("getExifSoftware failed");
    }

#endif

    if (mParameters.useJpegExifRotation()) {
        int16_t orientation;
        switch (mParameters.getJpegExifRotation()) {
        case 0:
            orientation = 1;
            break;
        case 90:
            orientation = 6;
            break;
        case 180:
            orientation = 3;
            break;
        case 270:
            orientation = 8;
            break;
        default:
            orientation = 1;
            break;
        }
        exif->addEntry(EXIFTAGID_ORIENTATION,
                EXIF_SHORT,
                1,
                (void *)&orientation);
        exif->addEntry(EXIFTAGID_TN_ORIENTATION,
                EXIF_SHORT,
                1,
                (void *)&orientation);
    }

    return exif;
}

/*===========================================================================
 * FUNCTION   : setHistogram
 *
 * DESCRIPTION: set if histogram should be enabled
 *
 * PARAMETERS :
 *   @histogram_en : bool flag if histogram should be enabled
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
{
    return mParameters.setHistogram(histogram_en);
}

/*===========================================================================
 * FUNCTION   : setFaceDetection
 *
 * DESCRIPTION: set if face detection should be enabled
 *
 * PARAMETERS :
 *   @enabled : bool flag if face detection should be enabled
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
{
    return mParameters.setFaceDetection(enabled, true);
}

/*===========================================================================
 * FUNCTION   : isCaptureShutterEnabled
 *
 * DESCRIPTION: Check whether shutter should be triggered immediately after
 *              capture
 *
 * PARAMETERS :
 *
 * RETURN     : true - regular capture
 *              false - other type of capture
 *==========================================================================*/
bool QCamera2HardwareInterface::isCaptureShutterEnabled()
{
    char prop[PROPERTY_VALUE_MAX];
    memset(prop, 0, sizeof(prop));
    property_get("persist.camera.feature.shutter", prop, "0");
    int enableShutter = atoi(prop);
    return enableShutter == 1;
}

/*===========================================================================
 * FUNCTION   : needProcessPreviewFrame
 *
 * DESCRIPTION: returns whether preview frame need to be displayed
 *
 * PARAMETERS :
 *   @frameID : frameID of frame to be processed
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
{
    return (((m_stateMachine.isPreviewRunning()) &&
            (!isDisplayFrameToSkip(frameID)) &&
            (!mParameters.isInstantAECEnabled())) ||
            (isPreviewRestartEnabled()));
}

/*===========================================================================
 * FUNCTION   : needSendPreviewCallback
 *
 * DESCRIPTION: returns whether preview frame need to callback to APP
 *
 * PARAMETERS :
 *
 * RETURN     : true - need preview frame callbck
 *              false - not send preview frame callback
 *==========================================================================*/
bool QCamera2HardwareInterface::needSendPreviewCallback()
{
    return m_stateMachine.isPreviewRunning()
            && (mDataCb != NULL)
            && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
            && m_stateMachine.isPreviewCallbackNeeded();
};

/*===========================================================================
 * FUNCTION   : setDisplaySkip
 *
 * DESCRIPTION: set range of frames to skip for preview
 *
 * PARAMETERS :
 *   @enabled : TRUE to start skipping frame to display
                FALSE to stop skipping frame to display
 *   @skipCnt : Number of frame to skip. 0 by default
 *
 * RETURN     : None
 *==========================================================================*/
void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
{
    pthread_mutex_lock(&mGrallocLock);
    if (enabled) {
        setDisplayFrameSkip();
        setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
    } else {
        setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
    }
    pthread_mutex_unlock(&mGrallocLock);
}

/*===========================================================================
 * FUNCTION   : setDisplayFrameSkip
 *
 * DESCRIPTION: set range of frames to skip for preview
 *
 * PARAMETERS :
 *   @start   : frameId to start skip
 *   @end     : frameId to stop skip
 *
 * RETURN     : None
 *==========================================================================*/
void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
        uint32_t end)
{
    if (start == 0) {
        mFrameSkipStart = 0;
        mFrameSkipEnd = 0;
        return;
    }
    if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
        mFrameSkipStart = start;
    }
    if ((end == 0) || (end > mFrameSkipEnd)) {
        mFrameSkipEnd = end;
    }
}

/*===========================================================================
 * FUNCTION   : isDisplayFrameToSkip
 *
 * DESCRIPTION: function to determin if input frame falls under skip range
 *
 * PARAMETERS :
 *   @frameId : frameId to verify
 *
 * RETURN     : true : need to skip
 *              false: no need to skip
 *==========================================================================*/
bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
{
    return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
            (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
}

/*===========================================================================
 * FUNCTION   : getSnapshotHandle
 *
 * DESCRIPTION: Get the camera handle for snapshot based on the bundlesnapshot
 *              flag and active camera state
 *
 * PARAMETERS : None
 *
 * RETURN     : camera handle for snapshot
 *
 *==========================================================================*/
uint32_t QCamera2HardwareInterface::getSnapshotHandle()
{
    uint32_t snapshotHandle = 0;

    if ((mActiveCameras == MM_CAMERA_DUAL_CAM) && mBundledSnapshot) {
        snapshotHandle = mCameraHandle->camera_handle;
    } else {
        snapshotHandle = (mMasterCamera == MM_CAMERA_TYPE_MAIN) ?
                get_main_camera_handle(mCameraHandle->camera_handle) :
                get_aux_camera_handle(mCameraHandle->camera_handle);
    }

    return snapshotHandle;
}

/*===========================================================================
 * FUNCTION   : prepareHardwareForSnapshot
 *
 * DESCRIPTION: prepare hardware for snapshot, such as LED
 *
 * PARAMETERS :
 *   @afNeeded: flag indicating if Auto Focus needs to be done during preparation
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
{
    ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_HW_FOR_SNAPSHOT);
    LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
    return mCameraHandle->ops->prepare_snapshot(getSnapshotHandle(),
                                                afNeeded);
}

/*===========================================================================
 * FUNCTION   : needFDMetadata
 *
 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
 *
 * PARAMETERS :
 *   @channel_type: channel type
 *
  * RETURN     : true: needed
 *              false: no need
 *==========================================================================*/
bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
{
    //Note: Currently we only process ZSL channel
    bool value = false;
    if(channel_type == QCAMERA_CH_TYPE_ZSL){
        //check if FD requirement is enabled
        if(mParameters.isSnapshotFDNeeded() &&
           mParameters.isFaceDetectionEnabled()){
            value = true;
            LOGH("Face Detection metadata is required in ZSL mode.");
        }
    }

    return value;
}

/*===========================================================================
 * FUNCTION   : deferredWorkRoutine
 *
 * DESCRIPTION: data process routine that executes deferred tasks
 *
 * PARAMETERS :
 *   @data    : user data ptr (QCamera2HardwareInterface)
 *
 * RETURN     : None
 *==========================================================================*/
void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
{
    int running = 1;
    int ret;
    uint8_t is_active = FALSE;
    int32_t job_status = 0;

    QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
    QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
    cmdThread->setName("CAM_defrdWrk");

    do {
        do {
            ret = cam_sem_wait(&cmdThread->cmd_sem);
            if (ret != 0 && errno != EINVAL) {
                LOGE("cam_sem_wait error (%s)",
                         strerror(errno));
                return NULL;
            }
        } while (ret != 0);

        // we got notified about new cmd avail in cmd queue
        camera_cmd_type_t cmd = cmdThread->getCmd();
        LOGD("cmd: %d", cmd);
        switch (cmd) {
        case CAMERA_CMD_TYPE_START_DATA_PROC:
            LOGH("start data proc");
            is_active = TRUE;
            break;
        case CAMERA_CMD_TYPE_STOP_DATA_PROC:
            LOGH("stop data proc");
            is_active = FALSE;
            // signal cmd is completed
            cam_sem_post(&cmdThread->sync_sem);
            break;
        case CAMERA_CMD_TYPE_DO_NEXT_JOB:
            {
                DefWork *dw =
                    reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());

                if ( NULL == dw ) {
                    LOGE("Invalid deferred work");
                    break;
                }

                switch( dw->cmd ) {
                case CMD_DEF_ALLOCATE_BUFF:
                    {
                        QCameraChannel * pChannel = dw->args.allocArgs.ch;

                        if ( NULL == pChannel ) {
                            LOGE("Invalid deferred work channel");
                            job_status = BAD_VALUE;
                            break;
                        }

                        cam_stream_type_t streamType = dw->args.allocArgs.type;
                        LOGH("Deferred buffer allocation started for stream type: %d",
                                 streamType);

                        uint32_t iNumOfStreams = pChannel->getNumOfStreams();
                        QCameraStream *pStream = NULL;
                        for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
                            pStream = pChannel->getStreamByIndex(i);

                            if ( NULL == pStream ) {
                                job_status = BAD_VALUE;
                                break;
                            }

                            if ( pStream->isTypeOf(streamType)) {
                                if ( pStream->allocateBuffers() ) {
                                    LOGE("Error allocating buffers !!!");
                                    job_status =  NO_MEMORY;
                                    pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                            CAMERA_ERROR_UNKNOWN, 0);
                                }
                                break;
                            }
                        }
                    }
                    break;
                case CMD_DEF_PPROC_START:
                    {
                        int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
                        if (ret != NO_ERROR) {
                            job_status = ret;
                            LOGE("PPROC Start failed");
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                            break;
                        }
                        QCameraChannel * pChannel = dw->args.pprocArgs;
                        assert(pChannel);

                        if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
                            LOGE("cannot start postprocessor");
                            job_status = BAD_VALUE;
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                        }
                    }
                    break;
                case CMD_DEF_METADATA_ALLOC:
                    {
                        int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
                        if (ret != NO_ERROR) {
                            job_status = ret;
                            LOGE("Metadata alloc failed");
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                            break;
                        }
                        pme->mMetadataMem = new QCameraMetadataStreamMemory(
                                QCAMERA_ION_USE_CACHE);

                        if (pme->mMetadataMem == NULL) {
                            LOGE("Unable to allocate metadata buffers");
                            job_status = BAD_VALUE;
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                        } else {
                            int32_t rc = pme->mMetadataMem->allocate(
                                    dw->args.metadataAllocArgs.bufferCnt,
                                    dw->args.metadataAllocArgs.size);
                            if (rc < 0) {
                                delete pme->mMetadataMem;
                                pme->mMetadataMem = NULL;
                            }
                        }
                     }
                     break;
                case CMD_DEF_CREATE_JPEG_SESSION:
                    {
                        QCameraChannel * pChannel = dw->args.pprocArgs;
                        assert(pChannel);

                        int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
                        if (ret != NO_ERROR) {
                            job_status = ret;
                            LOGE("Jpeg create failed");
                            break;
                        }

                        if (pme->m_postprocessor.createJpegSession(pChannel)
                            != NO_ERROR) {
                            LOGE("cannot create JPEG session");
                            job_status = UNKNOWN_ERROR;
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                        }
                    }
                    break;
                case CMD_DEF_PPROC_INIT:
                    {
                        int32_t rc = NO_ERROR;

                        jpeg_encode_callback_t jpegEvtHandle =
                                dw->args.pprocInitArgs.jpeg_cb;
                        void* user_data = dw->args.pprocInitArgs.user_data;
                        QCameraPostProcessor *postProcessor =
                                &(pme->m_postprocessor);
                        uint32_t cameraId = pme->mCameraId;
                        cam_capability_t *capability =
                                gCamCapability[cameraId];
                        cam_padding_info_t padding_info;
                        cam_padding_info_t& cam_capability_padding_info =
                                capability->padding_info;

                        if(!pme->mJpegClientHandle) {
                            rc = pme->initJpegHandle();
                            if (rc != NO_ERROR) {
                                LOGE("Error!! creating JPEG handle failed");
                                job_status = UNKNOWN_ERROR;
                                pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                        CAMERA_ERROR_UNKNOWN, 0);
                                break;
                            }
                        }
                        LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);

                        rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
                                &pme->mJpegMpoHandle,
                                pme->mJpegClientHandle);
                        if (rc != 0) {
                            LOGE("Error!! set JPEG handle failed");
                            job_status = UNKNOWN_ERROR;
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                            break;
                        }

                        /* get max pic size for jpeg work buf calculation*/
                        rc = postProcessor->init(jpegEvtHandle, user_data);

                        if (rc != NO_ERROR) {
                            LOGE("cannot init postprocessor");
                            job_status = UNKNOWN_ERROR;
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                            break;
                        }

                        // update padding info from jpeg
                        postProcessor->getJpegPaddingReq(padding_info);
                        if (cam_capability_padding_info.width_padding <
                                padding_info.width_padding) {
                            cam_capability_padding_info.width_padding =
                                    padding_info.width_padding;
                        }
                        if (cam_capability_padding_info.height_padding <
                                padding_info.height_padding) {
                            cam_capability_padding_info.height_padding =
                                    padding_info.height_padding;
                        }
                        if (cam_capability_padding_info.plane_padding !=
                                padding_info.plane_padding) {
                            cam_capability_padding_info.plane_padding =
                                    mm_stream_calc_lcm(
                                    cam_capability_padding_info.plane_padding,
                                    padding_info.plane_padding);
                        }
                        if (cam_capability_padding_info.offset_info.offset_x
                                != padding_info.offset_info.offset_x) {
                            cam_capability_padding_info.offset_info.offset_x =
                                    mm_stream_calc_lcm (
                                    cam_capability_padding_info.offset_info.offset_x,
                                    padding_info.offset_info.offset_x);
                        }
                        if (cam_capability_padding_info.offset_info.offset_y
                                != padding_info.offset_info.offset_y) {
                            cam_capability_padding_info.offset_info.offset_y =
                            mm_stream_calc_lcm (
                                    cam_capability_padding_info.offset_info.offset_y,
                                    padding_info.offset_info.offset_y);
                        }
                    }
                    break;
                case CMD_DEF_PARAM_ALLOC:
                    {
                        int32_t rc = NO_ERROR;
                        if (pme->isDualCamera()) {
                            rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
                        } else {
                            rc = pme->mParameters.allocate();
                        }
                        // notify routine would not be initialized by this time.
                        // So, just update error job status
                        if (rc != NO_ERROR) {
                            job_status = rc;
                            LOGE("Param allocation failed");
                            break;
                        }
                    }
                    break;
                case CMD_DEF_PARAM_INIT:
                    {
                        int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
                        if (rc != NO_ERROR) {
                            job_status = rc;
                            LOGE("Param init failed");
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                            break;
                        }

                        uint32_t camId = pme->mCameraId;
                        cam_capability_t * cap = gCamCapability[camId];

                        if (pme->mCameraHandle == NULL) {
                            LOGE("Camera handle is null");
                            job_status = BAD_VALUE;
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                            break;
                        }

                        // Now PostProc need calibration data as initialization
                        // time for jpeg_open and calibration data is a
                        // get param for now, so params needs to be initialized
                        // before postproc init
                        rc = pme->mParameters.init(cap,
                                pme->mCameraHandle,
                                pme, pme->m_pFovControl);
                        if (rc != 0) {
                            job_status = UNKNOWN_ERROR;
                            LOGE("Parameter Initialization failed");
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                            break;
                        }

                        // Get related cam calibration only in
                        // dual camera mode
                        if ((pme->getRelatedCamSyncInfo()->sync_control ==
                                CAM_SYNC_RELATED_SENSORS_ON) || pme->isDualCamera()){
                            rc = pme->mParameters.getRelatedCamCalibration(
                                &(pme->mJpegMetadata.otp_calibration_data));
                            LOGD("Dumping Calibration Data Version Id %f rc %d",
                                    pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
                                    rc);
                            if (rc != 0) {
                                job_status = UNKNOWN_ERROR;
                                LOGE("getRelatedCamCalibration failed");
                                pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                        CAMERA_ERROR_UNKNOWN, 0);
                                break;
                            }
                            pme->m_bRelCamCalibValid = true;
                        }

                        pme->mJpegMetadata.sensor_mount_angle =
                            cap->sensor_mount_angle;
                        pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;

                        pme->mParameters.setMinPpMask(
                            cap->qcom_supported_feature_mask);
                        pme->mExifParams.debug_params =
                                (mm_jpeg_debug_exif_params_t *)
                                malloc(sizeof(mm_jpeg_debug_exif_params_t));
                        if (!pme->mExifParams.debug_params) {
                            LOGE("Out of Memory. Allocation failed for "
                                    "3A debug exif params");
                            job_status = NO_MEMORY;
                            pme->sendEvtNotify(CAMERA_MSG_ERROR,
                                    CAMERA_ERROR_UNKNOWN, 0);
                            break;
                        }
                        memset(pme->mExifParams.debug_params, 0,
                                sizeof(mm_jpeg_debug_exif_params_t));
                    }
                    break;
                case CMD_DEF_GENERIC:
                    {
                        BackgroundTask *bgTask = dw->args.genericArgs;
                        job_status = bgTask->bgFunction(bgTask->bgArgs);
                    }
                    break;
                default:
                    LOGE("Incorrect command : %d", dw->cmd);
                }

                pme->dequeueDeferredWork(dw, job_status);
            }
            break;
        case CAMERA_CMD_TYPE_EXIT:
            running = 0;
            break;
        default:
            break;
        }
    } while (running);

    return NULL;
}

/*===========================================================================
 * FUNCTION   : queueDeferredWork
 *
 * DESCRIPTION: function which queues deferred tasks
 *
 * PARAMETERS :
 *   @cmd     : deferred task
 *   @args    : deferred task arguments
 *
 * RETURN     : job id of deferred job
 *            : 0 in case of error
 *==========================================================================*/
uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
                                                      DeferWorkArgs args)
{
    Mutex::Autolock l(mDefLock);
    for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
        if (mDefOngoingJobs[i].mDefJobId == 0) {
            DefWork *dw = new DefWork(cmd, sNextJobId, args);
            if (!dw) {
                LOGE("out of memory.");
                return 0;
            }
            if (mCmdQueue.enqueue(dw)) {
                mDefOngoingJobs[i].mDefJobId = sNextJobId++;
                mDefOngoingJobs[i].mDefJobStatus = 0;
                if (sNextJobId == 0) { // handle overflow
                    sNextJobId = 1;
                }
                mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
                        FALSE,
                        FALSE);
                return mDefOngoingJobs[i].mDefJobId;
            } else {
                LOGD("Command queue not active! cmd = %d", cmd);
                delete dw;
                return 0;
            }
        }
    }
    return 0;
}

/*===========================================================================
 * FUNCTION   : initJpegHandle
 *
 * DESCRIPTION: Opens JPEG client and gets a handle.
 *                     Sends Dual cam calibration info if present
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::initJpegHandle() {
    // Check if JPEG client handle is present
    LOGH("E");
    if(!mJpegClientHandle) {
        mm_dimension max_size = {0, 0};
        cam_dimension_t size;

        mParameters.getMaxPicSize(size);
        max_size.w = size.width;
        max_size.h = size.height;

        if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
            if (m_bRelCamCalibValid) {
                mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
                        max_size, &mJpegMetadata);
            } else {
                mJpegClientHandle =  jpeg_open(&mJpegHandle, &mJpegMpoHandle,
                        max_size, NULL);
            }
        } else {
            mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
        }
        if (!mJpegClientHandle) {
            LOGE("Error !! jpeg_open failed!! ");
            return UNKNOWN_ERROR;
        }
        // Set JPEG initialized as true to signify that this camera
        // has initialized the handle
        mJpegHandleOwner = true;
    }
    LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
             mJpegHandleOwner, mJpegClientHandle, mCameraId);
    return NO_ERROR;
}

/*===========================================================================
 * FUNCTION   : deinitJpegHandle
 *
 * DESCRIPTION: Closes JPEG client using handle
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::deinitJpegHandle() {
    int32_t rc = NO_ERROR;
    LOGH("E");
    // Check if JPEG client handle is present and inited by this camera
    if(mJpegHandleOwner && mJpegClientHandle) {
        rc = mJpegHandle.close(mJpegClientHandle);
        if (rc != NO_ERROR) {
            LOGE("Error!! Closing mJpegClientHandle: %d failed",
                     mJpegClientHandle);
        }
        memset(&mJpegHandle, 0, sizeof(mJpegHandle));
        memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
        mJpegHandleOwner = false;
    }
    mJpegClientHandle = 0;
    LOGH("X rc = %d", rc);
    return rc;
}

/*===========================================================================
 * FUNCTION   : setJpegHandleInfo
 *
 * DESCRIPTION: sets JPEG client handle info
 *
 * PARAMETERS:
 *                  @ops                    : JPEG ops
 *                  @mpo_ops             : Jpeg MPO ops
 *                  @pJpegClientHandle : o/p Jpeg Client Handle
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
        mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {

    if (pJpegClientHandle && ops && mpo_ops) {
        LOGH("Setting JPEG client handle %d",
                pJpegClientHandle);
        memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
        memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
        mJpegClientHandle = pJpegClientHandle;
        return NO_ERROR;
    }
    else {
        LOGE("Error!! No Handle found: %d",
                pJpegClientHandle);
        return BAD_VALUE;
    }
}

/*===========================================================================
 * FUNCTION   : getJpegHandleInfo
 *
 * DESCRIPTION: gets JPEG client handle info
 *
 * PARAMETERS:
 *                  @ops                    : JPEG ops
 *                  @mpo_ops             : Jpeg MPO ops
 *                  @pJpegClientHandle : o/p Jpeg Client Handle
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
        mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {

    if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
        LOGE("Init PProc Deferred work failed");
        return UNKNOWN_ERROR;
    }
    // Copy JPEG ops if present
    if (ops && mpo_ops && pJpegClientHandle) {
        memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
        memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
        *pJpegClientHandle = mJpegClientHandle;
        LOGH("Getting JPEG client handle %d",
                pJpegClientHandle);
        return NO_ERROR;
    } else {
        return BAD_VALUE;
    }
}

/*===========================================================================
 * FUNCTION   : dequeueDeferredWork
 *
 * DESCRIPTION: function which dequeues deferred tasks
 *
 * PARAMETERS :
 *   @dw      : deferred work
 *   @jobStatus: deferred task job status
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
{
    Mutex::Autolock l(mDefLock);
    for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
        if (mDefOngoingJobs[i].mDefJobId == dw->id) {
            if (jobStatus != NO_ERROR) {
                mDefOngoingJobs[i].mDefJobStatus = jobStatus;
                LOGH("updating job status %d for id %d",
                         jobStatus, dw->id);
            } else {
                mDefOngoingJobs[i].mDefJobId = 0;
                mDefOngoingJobs[i].mDefJobStatus = 0;
            }
            delete dw;
            mDefCond.broadcast();
            return NO_ERROR;
        }
    }

    return UNKNOWN_ERROR;
}

/*===========================================================================
 * FUNCTION   : getDefJobStatus
 *
 * DESCRIPTION: Gets if a deferred task is success/fail
 *
 * PARAMETERS :
 *   @job_id  : deferred task id
 *
 * RETURN     : NO_ERROR if the job success, otherwise false
 *
 * PRECONDITION : mDefLock is held by current thread
 *==========================================================================*/
int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
{
    for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
        if (mDefOngoingJobs[i].mDefJobId == job_id) {
            if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
                LOGE("job_id (%d) was failed", job_id);
                return mDefOngoingJobs[i].mDefJobStatus;
            }
            else
                return NO_ERROR;
        }
    }
    return NO_ERROR;
}


/*===========================================================================
 * FUNCTION   : checkDeferredWork
 *
 * DESCRIPTION: checks if a deferred task is in progress
 *
 * PARAMETERS :
 *   @job_id  : deferred task id
 *
 * RETURN     : true if the task exists, otherwise false
 *
 * PRECONDITION : mDefLock is held by current thread
 *==========================================================================*/
bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
{
    for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
        if (mDefOngoingJobs[i].mDefJobId == job_id) {
            return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
        }
    }
    return false;
}

/*===========================================================================
 * FUNCTION   : waitDeferredWork
 *
 * DESCRIPTION: waits for a deferred task to finish
 *
 * PARAMETERS :
 *   @job_id  : deferred task id
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
{
    Mutex::Autolock l(mDefLock);

    if (job_id == 0) {
        LOGD("Invalid job id %d", job_id);
        return NO_ERROR;
    }

    while (checkDeferredWork(job_id) == true ) {
        mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
    }
    return getDefJobStatus(job_id);
}

/*===========================================================================
 * FUNCTION   : scheduleBackgroundTask
 *
 * DESCRIPTION: Run a requested task in the deferred thread
 *
 * PARAMETERS :
 *   @bgTask  : Task to perform in the background
 *
 * RETURN     : job id of deferred job
 *            : 0 in case of error
 *==========================================================================*/
uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
{
    DeferWorkArgs args;
    memset(&args, 0, sizeof(DeferWorkArgs));
    args.genericArgs = bgTask;

    return queueDeferredWork(CMD_DEF_GENERIC, args);
}

/*===========================================================================
 * FUNCTION   : waitForBackgroundTask
 *
 * DESCRIPTION: Wait for a background task to complete
 *
 * PARAMETERS :
 *   @taskId  : Task id to wait for
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
{
    return waitDeferredWork(taskId);
}

/*===========================================================================
 * FUNCTION   : needDeferedAllocation
 *
 * DESCRIPTION: Function to decide background task for streams
 *
 * PARAMETERS :
 *   @stream_type  : stream type
 *
 * RETURN     : true - if background task is needed
 *              false -  if background task is NOT needed
 *==========================================================================*/
bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
{
    if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
            || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
        return FALSE;
    }

    if ((stream_type == CAM_STREAM_TYPE_RAW)
            && (mParameters.getofflineRAW() && !mParameters.getQuadraCfa())) {
        return FALSE;
    }

    if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
            && (!mParameters.getRecordingHintValue())){
        return TRUE;
    }

    if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
            || (stream_type == CAM_STREAM_TYPE_METADATA)
            || (stream_type == CAM_STREAM_TYPE_RAW)
            || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
        return TRUE;
    }

    if (stream_type == CAM_STREAM_TYPE_VIDEO) {
        return FALSE;
    }
    return FALSE;
}

/*===========================================================================
 * FUNCTION   : needSyncCB
 *
 * DESCRIPTION: Decide syncronous callback per stream
 *
 * PARAMETERS :
 *  @stream_type: stream type
 *
 * RETURN     : true - if background task is needed
 *              false -  if background task is NOT needed
 *==========================================================================*/
bool QCamera2HardwareInterface::needSyncCB(cam_stream_type_t stream_type)
{
#ifdef TARGET_TS_MAKEUP
    int whiteLevel, cleanLevel;
    if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == TRUE) {
        return FALSE;
    }
#endif

    char value[PROPERTY_VALUE_MAX];
    property_get("persist.camera.preview.sync_cb", value, "1");
    if ((atoi(value) == 1) && (stream_type == CAM_STREAM_TYPE_PREVIEW)) {
        return TRUE;
    }
    return FALSE;
}

/*===========================================================================
 * FUNCTION   : isRegularCapture
 *
 * DESCRIPTION: Check configuration for regular catpure
 *
 * PARAMETERS :
 *
 * RETURN     : true - regular capture
 *              false - other type of capture
 *==========================================================================*/
bool QCamera2HardwareInterface::isRegularCapture()
{
    bool ret = false;

    if (numOfSnapshotsExpected() == 1 &&
        !isLongshotEnabled() &&
        !mParameters.isHDREnabled() &&
        !mParameters.getRecordingHintValue() &&
        !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
            ret = true;
    }
    return ret;
}

/*===========================================================================
 * FUNCTION   : needOfflineReprocessing
 *
 * DESCRIPTION: Check for offline reprocessing
 *
 * PARAMETERS :
 *
 * RETURN     : true - regular capture
 *              false - other type of capture
 *==========================================================================*/
bool QCamera2HardwareInterface::needOfflineReprocessing()
{
    bool ret = false;
    if (isRegularCapture()
            || isDualCamera()) {
        ret = true;
    }
    return ret;
}

/*===========================================================================
 * FUNCTION   : getLogLevel
 *
 * DESCRIPTION: Reads the log level property into a variable
 *
 * PARAMETERS :
 *   None
 *
 * RETURN     :
 *   None
 *==========================================================================*/
void QCamera2HardwareInterface::getLogLevel()
{
    char prop[PROPERTY_VALUE_MAX];

    property_get("persist.camera.kpi.debug", prop, "0");
    gKpiDebugLevel = atoi(prop);
    return;
}

/*===========================================================================
 * FUNCTION   : getSensorType
 *
 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
 *
 * PARAMETERS :
 *   None
 *
 * RETURN     : Type of sensor - bayer or YUV
 *
 *==========================================================================*/
cam_sensor_t QCamera2HardwareInterface::getSensorType()
{
    return gCamCapability[mCameraId]->sensor_type.sens_type;
}

/*===========================================================================
 * FUNCTION   : startRAWChannel
 *
 * DESCRIPTION: start RAW Channel
 *
 * PARAMETERS :
 *   @pChannel  : Src channel to link this RAW channel.
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
{
    int32_t rc = NO_ERROR;
    QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
    if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
        // Find and try to link a metadata stream from preview channel
        QCameraStream *pMetaStream = NULL;

        if (pMetaChannel != NULL) {
            uint32_t streamNum = pMetaChannel->getNumOfStreams();
            QCameraStream *pStream = NULL;
            for (uint32_t i = 0 ; i < streamNum ; i++ ) {
                pStream = pMetaChannel->getStreamByIndex(i);
                if ((NULL != pStream) &&
                        (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
                    pMetaStream = pStream;
                    break;
                }
            }

            if (NULL != pMetaStream) {
                rc = pChannel->linkStream(pMetaChannel, pMetaStream);
                if (NO_ERROR != rc) {
                    LOGE("Metadata stream link failed %d", rc);
                }
            }
        }
        rc = pChannel->start();
    }
    return rc;
}

/*===========================================================================
 * FUNCTION   : startRecording
 *
 * DESCRIPTION: start recording impl
 *
 * PARAMETERS : none
 *
 * RETURN     : int32_t type of status
 *              NO_ERROR  -- success
 *              none-zero failure code
 *==========================================================================*/
int32_t QCamera2HardwareInterface::stopRAWChannel()
{
    int32_t rc = NO_ERROR;
    rc = stopChannel(QCAMERA_CH_TYPE_RAW);
    return rc;
}

/*===========================================================================
 * FUNCTION   : isLowPowerMode
 *
 * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
 *
 * PARAMETERS :
 *   None
 *
 * RETURN     : TRUE/FALSE
 *
 *==========================================================================*/
bool QCamera2HardwareInterface::isLowPowerMode()
{
    cam_dimension_t dim;
    mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);

    char prop[PROPERTY_VALUE_MAX];
    property_get("camera.lowpower.record.enable", prop, "0");
    int enable = atoi(prop);

    //Enable low power mode if :
    //1. Video resolution is 2k (2048x1080) or above and
    //2. camera.lowpower.record.enable is set

    bool isLowpower = mParameters.getRecordingHintValue() && enable
            && ((dim.width * dim.height) >= (2048 * 1080));
    return isLowpower;
}

/*===========================================================================
 * FUNCTION   : getBootToMonoTimeOffset
 *
 * DESCRIPTION: Calculate offset that is used to convert from
 *              clock domain of boot to monotonic
 *
 * PARAMETERS :
 *   None
 *
 * RETURN     : clock offset between boottime and monotonic time.
 *
 *==========================================================================*/
nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset()
{
    // try three times to get the clock offset, choose the one
    // with the minimum gap in measurements.
    const int tries = 3;
    nsecs_t bestGap, measured;
    for (int i = 0; i < tries; ++i) {
        const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
        const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
        const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
        const nsecs_t gap = tmono2 - tmono;
        if (i == 0 || gap < bestGap) {
            bestGap = gap;
            measured = tbase - ((tmono + tmono2) >> 1);
        }
    }
    return measured;
}

/*===========================================================================
 * FUNCTION   : fillDualCameraFOVControl
 *
 * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
 *
 * PARAMETERS : none
 *
 * RETURN     : none
 *==========================================================================*/
void QCamera2HardwareInterface::fillDualCameraFOVControl()
{
    qcamera_sm_internal_evt_payload_t *payload =
       (qcamera_sm_internal_evt_payload_t *)
       malloc(sizeof(qcamera_sm_internal_evt_payload_t));
    if (NULL != payload) {
        memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
        payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
        int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
        if (rc != NO_ERROR) {
            LOGE("processEvt Dual camera fill FOV control failed");
            free(payload);
            payload = NULL;
        }
    } else {
        LOGE("No memory for Dual camera fill FOV control event");
    }
}

}; // namespace qcamera
