camera: update AU_LINUX_ANDROID_LA.BF64.1.2.9.05.01.00.089.276

6105299 QCamera2: Perf lock for camera KPI HAL/HAL3
4f444f9 Merge "Revert "QCamera2: Perf lock for camera KPI""
8ba6ac6 QCamera2/HAL3: Don't hardcode the number of batch buffers
af0843e Revert "QCamera2: Perf lock for camera KPI"

Change-Id: Ibf5d28f2160b0e6bbc25dda75598b32a8b47a54e
diff --git a/QCamera2/Android.mk b/QCamera2/Android.mk
index bb3e846..86591c5 100644
--- a/QCamera2/Android.mk
+++ b/QCamera2/Android.mk
@@ -8,6 +8,7 @@
         util/QCameraCmdThread.cpp \
         util/QCameraQueue.cpp \
         util/QCameraFlash.cpp \
+        util/QCameraPerf.cpp \
         QCamera2Hal.cpp \
         QCamera2Factory.cpp
 
diff --git a/QCamera2/HAL/QCamera2HWI.cpp b/QCamera2/HAL/QCamera2HWI.cpp
index 98ce78f..fcc60fb 100644
--- a/QCamera2/HAL/QCamera2HWI.cpp
+++ b/QCamera2/HAL/QCamera2HWI.cpp
@@ -39,7 +39,6 @@
 #include <utils/Trace.h>
 #include <gralloc_priv.h>
 #include <gui/Surface.h>
-#include <dlfcn.h>
 
 #include "QCamera2HWI.h"
 #include "QCameraMem.h"
@@ -57,8 +56,6 @@
 //for the output of pproc
 #define CAMERA_PPROC_OUT_BUFFER_MULTIPLIER 2
 
-#define ALL_CPUS_PWR_CLPS_DIS 0x101
-#define INDEFINITE_DURATION     0
 
 #define HDR_CONFIDENCE_THRESHOLD 0.4
 
@@ -336,9 +333,8 @@
         ALOGE("NULL camera device");
         return;
     }
-    hw->m_perfLock.lock_acq();
-
     ALOGI("[KPI Perf] %s: E PROFILE_STOP_PREVIEW", __func__);
+    hw->m_perfLock.lock_acq();
     hw->lockAPI();
     qcamera_api_result_t apiResult;
     int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
@@ -649,10 +645,10 @@
         return BAD_VALUE;
     }
     ALOGI("[KPI Perf] %s: E PROFILE_TAKE_PICTURE", __func__);
+    hw->lockAPI();
     if (!hw->mLongshotEnabled) {
         hw->m_perfLock.lock_acq();
     }
-    hw->lockAPI();
     qcamera_api_result_t apiResult;
 
    /** Added support for Retro-active Frames:
@@ -727,10 +723,6 @@
         }
     }
     hw->unlockAPI();
-    if (ret != NO_ERROR) {
-      hw->m_perfLock.lock_rel();
-    }
-
     ALOGI("[KPI Perf] %s: X", __func__);
     return ret;
 }
@@ -997,7 +989,6 @@
     ATRACE_CALL();
     int ret = NO_ERROR;
     ALOGI("[KPI Perf] %s: E",__func__);
-
     QCamera2HardwareInterface *hw =
         reinterpret_cast<QCamera2HardwareInterface *>(
             reinterpret_cast<camera_device_t *>(hw_dev)->priv);
@@ -1006,7 +997,6 @@
         return BAD_VALUE;
     }
     delete hw;
-
     ALOGI("[KPI Perf] %s: X",__func__);
     return ret;
 }
@@ -1150,9 +1140,8 @@
     }
 #endif
 
-    m_perfLock.lock_init();
-
     memset(mDeffOngoingJobs, 0, sizeof(mDeffOngoingJobs));
+    m_perfLock.lock_init();
 
     mDefferedWorkThread.launch(defferedWorkRoutine, this);
     mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
@@ -1169,10 +1158,10 @@
  *==========================================================================*/
 QCamera2HardwareInterface::~QCamera2HardwareInterface()
 {
-    m_perfLock.lock_acq();
     mDefferedWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
     mDefferedWorkThread.exit();
 
+    m_perfLock.lock_acq();
     lockAPI();
     m_smThreadActive = false;
     unlockAPI();
@@ -1211,9 +1200,7 @@
     }
     ALOGI("[KPI Perf] %s: E PROFILE_OPEN_CAMERA camera id %d",
         __func__,mCameraId);
-
     m_perfLock.lock_acq();
-
     rc = openCamera();
     if (rc == NO_ERROR){
         *hw_device = &mCameraDevice.common;
@@ -3417,6 +3404,7 @@
     unconfigureAdvancedCapture();
 
     mParameters.setDisplayFrame(TRUE);
+
     if (!mLongshotEnabled) {
         m_perfLock.lock_rel();
     }
@@ -7790,169 +7778,4 @@
     return gCamCaps[mCameraId]->sensor_type.sens_type;
 }
 
-/*===========================================================================
- * FUNCTION   : lock_init
- *
- * DESCRIPTION: opens the performance lib and initilizes the perf lock functions
- *
- * PARAMETERS :
- *   None
- *
- * RETURN     : void
- *
- *==========================================================================*/
-void QCameraPerfLock::lock_init()
-{
-    const char *rc;
-    char value[PROPERTY_VALUE_MAX];
-    int len;
-    property_get("persist.camera.perflock.enable", value, "0");
-    mPerfLockEnable = atoi(value);
-    if (mPerfLockEnable) {
-        ALOGI("%s E", __func__);
-        perf_lock_acq = NULL;
-        perf_lock_rel = NULL;
-        mPerfLockHandle = 0;
-        /* Retrieve name of vendor extension library */
-        if (property_get("ro.vendor.extension_library", value, NULL)<= 0) {
-            return;
-        }
-
-        dlhandle = dlopen(value, RTLD_NOW | RTLD_LOCAL);
-
-        if (dlhandle == NULL) {
-            return;
-        }
-
-        dlerror();
-
-        perf_lock_acq = (int (*) (int, int, int[], int))dlsym(dlhandle, "perf_lock_acq");
-        if ((rc = dlerror()) != NULL) {
-            ALOGE("failed to perf_lock_acq function handle");
-            goto cleanup;
-        }
-
-        perf_lock_rel = (int (*) (int))dlsym(dlhandle, "perf_lock_rel");
-        if ((rc = dlerror()) != NULL) {
-            ALOGE("failed to perf_lock_rel function handle");
-            goto cleanup;
-        }
-        ALOGI("%s X", __func__);
-        return;
-
-    cleanup:
-        perf_lock_acq  = NULL;
-        perf_lock_rel  = NULL;
-        mPerfLockEnable = 0;
-        if (dlhandle) {
-            dlclose(dlhandle);
-            dlhandle = NULL;
-        }
-        ALOGI("%s X", __func__);
-    }
-}
-
-/*===========================================================================
- * FUNCTION   : lock_deinit
- *
- * DESCRIPTION: deinitialize the perf lock parameters
- *
- * PARAMETERS :
- *   None
- *
- * RETURN     : void
- *
- *==========================================================================*/
-void QCameraPerfLock::lock_deinit()
-{
-    if (mPerfLockEnable) {
-        ALOGI("%s E", __func__);
-        pthread_mutex_lock(&dl_mutex);
-        if (dlhandle) {
-            perf_lock_acq  = NULL;
-            perf_lock_rel  = NULL;
-
-            dlclose(dlhandle);
-            dlhandle       = NULL;
-        }
-        pthread_mutex_unlock(&dl_mutex);
-        ALOGI("%s X", __func__);
-    }
-}
-
-/*===========================================================================
- * FUNCTION   : lock_acq
- *
- * DESCRIPTION: acquire the performance lock
- *
- * PARAMETERS :
- *   None
- *
- * RETURN     : int32_t type of status
- *              NO_ERROR  -- success
- *              none-zero failure code
- *
- *==========================================================================*/
-int32_t QCameraPerfLock::lock_acq()
-{
-    int ret = -1;
-    if (mPerfLockEnable) {
-        int32_t perf_lock_params[] = { ALL_CPUS_PWR_CLPS_DIS};
-        ALOGI("%s E", __func__);
-        pthread_mutex_lock(&dl_mutex);
-        if ((NULL != perf_lock_acq) && (0 == mPerfLockHandle)) {
-            ret = (*perf_lock_acq)(mPerfLockHandle, INDEFINITE_DURATION, perf_lock_params,
-                                   sizeof(perf_lock_params) / sizeof(int32_t));
-            ALOGE("%s ret %d", __func__, ret);
-            if (ret < 0) {
-                ALOGE("failed to acquire lock");
-            }
-        }
-        mPerfLockHandle++;
-        CDBG_HIGH("%s perf_handle_acq %d ",__func__, mPerfLockHandle );
-        pthread_mutex_unlock(&dl_mutex);
-        ALOGI("%s X", __func__);
-
-    }
-    return ret;
-}
-
-/*===========================================================================
- * FUNCTION   : lock_rel
- *
- * DESCRIPTION: release the performance lock
- *
- * PARAMETERS :
- *   None
- *
- * RETURN     : int32_t type of status
- *              NO_ERROR  -- success
- *              none-zero failure code
- *
- *==========================================================================*/
-int32_t QCameraPerfLock::lock_rel()
-{
-    int ret = -1;
-    if (mPerfLockEnable) {
-        ALOGI("%s E", __func__);
-        pthread_mutex_lock(&dl_mutex);
-        mPerfLockHandle--;
-        if (mPerfLockHandle < 0) {
-            ALOGE("Error: mPerfLockHandle < 0,check if lock is released properly");
-            mPerfLockHandle = 0;
-        }
-        CDBG_HIGH("%s perf_handle_rel %d ",__func__, mPerfLockHandle );
-
-        if ((NULL != perf_lock_rel) && (0 == mPerfLockHandle)) {
-            ret = (*perf_lock_rel)(mPerfLockHandle);
-            if (ret < 0) {
-                ALOGE("failed to release lock");
-            }
-        }
-        pthread_mutex_unlock(&dl_mutex);
-        ALOGI("%s X", __func__);
-    }
-    return ret;
-}
-
 }; // namespace qcamera
diff --git a/QCamera2/HAL/QCamera2HWI.h b/QCamera2/HAL/QCamera2HWI.h
index 9c3bc3a..415b3a0 100644
--- a/QCamera2/HAL/QCamera2HWI.h
+++ b/QCamera2/HAL/QCamera2HWI.h
@@ -46,6 +46,7 @@
 #include "QCameraPostProc.h"
 #include "QCameraThermalAdapter.h"
 #include "QCameraMem.h"
+#include "QCameraPerf.h"
 
 extern "C" {
 #include <mm_camera_interface.h>
@@ -194,22 +195,6 @@
     QCameraCmdThread mProcTh;
     bool             mActive;
 };
-
-class QCameraPerfLock {
-public:
-    void    lock_init();
-    void    lock_deinit();
-    int32_t lock_rel();
-    int32_t lock_acq();
-private:
-    int32_t        (*perf_lock_acq)(int, int, int[], int);
-    int32_t        (*perf_lock_rel)(int);
-    void           *dlhandle;
-    uint32_t        mPerfLockEnable;
-    pthread_mutex_t dl_mutex;
-    int32_t         mPerfLockHandle;  // Performance lock library handle
-};
-
 class QCamera2HardwareInterface : public QCameraAllocator,
         public QCameraThermalCallback, public QCameraAdjustFPS
 {
diff --git a/QCamera2/HAL/QCamera2HWICallbacks.cpp b/QCamera2/HAL/QCamera2HWICallbacks.cpp
index d11585d..c73ff13 100644
--- a/QCamera2/HAL/QCamera2HWICallbacks.cpp
+++ b/QCamera2/HAL/QCamera2HWICallbacks.cpp
@@ -132,6 +132,7 @@
 
     /* indicate the parent that capture is done */
     pme->captureDone();
+
     // save a copy for the superbuf
     mm_camera_super_buf_t* frame =
                (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
@@ -399,6 +400,7 @@
         ALOGE("%s: Capture channel doesn't exist, return here", __func__);
         return;
     }
+
     // save a copy for the superbuf
     mm_camera_super_buf_t* frame =
                (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
diff --git a/QCamera2/HAL3/QCamera3HWI.cpp b/QCamera2/HAL3/QCamera3HWI.cpp
index 7e612b2..3396c7e 100755
--- a/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/QCamera2/HAL3/QCamera3HWI.cpp
@@ -81,8 +81,6 @@
 #define DEFAULT_VIDEO_FPS      (30.0)
 #define MAX_HFR_BATCH_SIZE     (8)
 #define REGIONS_TUPLE_COUNT    5
-#define MAX_INFLIGHT_HFR_REQUESTS (48)
-#define MIN_INFLIGHT_HFR_REQUESTS (40)
 
 #define METADATA_MAP_SIZE(MAP) (sizeof(MAP)/sizeof(MAP[0]))
 
@@ -352,6 +350,7 @@
       mLdafCalibExist(false)
 {
     getLogLevel();
+    m_perfLock.lock_init();
     mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
     mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_3;
     mCameraDevice.common.close = close_camera_device;
@@ -413,9 +412,14 @@
 QCamera3HardwareInterface::~QCamera3HardwareInterface()
 {
     CDBG("%s: E", __func__);
+
+    /* Turn off video hint prior to acquiring perfLock in case they
+     * conflict with each other */
+    updatePowerHint(m_bIsVideo, false);
+
+    m_perfLock.lock_acq();
+
     /* We need to stop all streams before deleting any stream */
-
-
     if (mRawDumpChannel) {
         mRawDumpChannel->stop();
     }
@@ -436,9 +440,6 @@
         mAnalysisChannel->stop();
     }
 
-    /* Turn off video hint */
-    updatePowerHint(m_bIsVideo, false);
-
     for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
         it != mStreamInfo.end(); it++) {
         QCamera3ProcessingChannel *channel = (*it)->channel;
@@ -501,6 +502,9 @@
         if (mDefaultMetadata[i])
             free_camera_metadata(mDefaultMetadata[i]);
 
+    m_perfLock.lock_rel();
+    m_perfLock.lock_deinit();
+
     pthread_cond_destroy(&mRequestCond);
 
     pthread_mutex_destroy(&mMutex);
@@ -605,13 +609,14 @@
         *hw_device = NULL;
         return PERMISSION_DENIED;
     }
-
+    m_perfLock.lock_acq();
     rc = openCamera();
     if (rc == 0) {
         *hw_device = &mCameraDevice.common;
     } else
         *hw_device = NULL;
 
+    m_perfLock.lock_rel();
     return rc;
 }
 
@@ -995,7 +1000,6 @@
      }
 #endif
 }
-
 /*===========================================================================
  * FUNCTION   : configureStreams
  *
@@ -1015,6 +1019,36 @@
     int rc = 0;
     bool bWasVideo = m_bIsVideo;
 
+    // Acquire perfLock before configure streams
+    m_perfLock.lock_acq();
+    rc = configureStreamsPerfLocked(streamList);
+    m_perfLock.lock_rel();
+
+    /* Update power hint after releasing perfLock in case they
+     * conflict with each other. */
+    updatePowerHint(bWasVideo, m_bIsVideo);
+
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : configureStreamsPerfLocked
+ *
+ * DESCRIPTION: configureStreams while perfLock is held.
+ *
+ * PARAMETERS :
+ *   @stream_list : streams to be configured
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int QCamera3HardwareInterface::configureStreamsPerfLocked(
+        camera3_stream_configuration_t *streamList)
+{
+    ATRACE_CALL();
+    int rc = 0;
+
     // Sanity check stream_list
     if (streamList == NULL) {
         ALOGE("%s: NULL stream configuration", __func__);
@@ -1834,9 +1868,9 @@
     deriveMinFrameDuration();
 
     /* Turn on video hint only if video stream is configured */
-    updatePowerHint(bWasVideo, m_bIsVideo);
 
     pthread_mutex_unlock(&mMutex);
+
     return rc;
 }
 
@@ -2856,7 +2890,7 @@
                 return rc;
             }
         }
-
+        m_perfLock.lock_acq();
         /* get eis information for stream configuration */
         cam_is_type_t is_type;
         char is_type_value[PROPERTY_VALUE_MAX];
@@ -2944,7 +2978,7 @@
         if (rc != NO_ERROR) {
             ALOGE("%s: Failed to get sensor output size", __func__);
             pthread_mutex_unlock(&mMutex);
-            return rc;
+            goto error_exit;
         }
 
         mCropRegionMapper.update(gCamCapability[mCameraId]->active_array_size.width,
@@ -2965,7 +2999,7 @@
                 if (NO_ERROR != rc) {
                     ALOGE("%s : Channel init failed %d", __func__, rc);
                     pthread_mutex_unlock(&mMutex);
-                    return rc;
+                    goto error_exit;
                 }
             }
         }
@@ -2985,7 +3019,8 @@
                 ALOGE("%s: registerBuffer failed",
                         __func__);
                 pthread_mutex_unlock(&mMutex);
-                return -ENODEV;
+                rc = -ENODEV;
+                goto error_exit;
             }
         }
 
@@ -3003,7 +3038,7 @@
             if (NO_ERROR != rc) {
                 ALOGE("%s : Channel initialization failed %d", __func__, rc);
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
 
@@ -3012,7 +3047,7 @@
             if (rc != NO_ERROR) {
                 ALOGE("%s: Error: Raw Dump Channel init failed", __func__);
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
         if (mSupportChannel) {
@@ -3020,7 +3055,7 @@
             if (rc < 0) {
                 ALOGE("%s: Support channel initialization failed", __func__);
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
         if (mAnalysisChannel) {
@@ -3028,7 +3063,7 @@
             if (rc < 0) {
                 ALOGE("%s: Analysis channel initialization failed", __func__);
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
         if (mDummyBatchChannel) {
@@ -3036,13 +3071,13 @@
             if (rc < 0) {
                 ALOGE("%s: mDummyBatchChannel setBatchSize failed", __func__);
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
             rc = mDummyBatchChannel->initialize(is_type);
             if (rc < 0) {
                 ALOGE("%s: mDummyBatchChannel initialization failed", __func__);
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
 
@@ -3052,7 +3087,7 @@
         if (rc < 0) {
             ALOGE("%s: META channel start failed", __func__);
             pthread_mutex_unlock(&mMutex);
-            return rc;
+            goto error_exit;
         }
 
         if (mAnalysisChannel) {
@@ -3061,7 +3096,7 @@
                 ALOGE("%s: Analysis channel start failed", __func__);
                 mMetadataChannel->stop();
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
 
@@ -3076,7 +3111,7 @@
                     mAnalysisChannel->stop();
                 }
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
         for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
@@ -3088,7 +3123,7 @@
             if (rc < 0) {
                 ALOGE("%s: channel start failed", __func__);
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
 
@@ -3112,9 +3147,15 @@
                 }
                 mMetadataChannel->stop();
                 pthread_mutex_unlock(&mMutex);
-                return rc;
+                goto error_exit;
             }
         }
+        goto no_error;
+error_exit:
+        m_perfLock.lock_rel();
+        return rc;
+no_error:
+        m_perfLock.lock_rel();
         mWokenUpByDaemon = false;
         mPendingLiveRequest = 0;
         mFirstConfiguration = false;
diff --git a/QCamera2/HAL3/QCamera3HWI.h b/QCamera2/HAL3/QCamera3HWI.h
index f93d83e..d10d26a 100755
--- a/QCamera2/HAL3/QCamera3HWI.h
+++ b/QCamera2/HAL3/QCamera3HWI.h
@@ -38,7 +38,7 @@
 #include "QCamera3HALHeader.h"
 #include "QCamera3Channel.h"
 #include "QCamera3CropRegionMapper.h"
-
+#include "QCameraPerf.h"
 #include <hardware/power.h>
 
 extern "C" {
@@ -159,6 +159,7 @@
 
     int initialize(const camera3_callback_ops_t *callback_ops);
     int configureStreams(camera3_stream_configuration_t *stream_list);
+    int configureStreamsPerfLocked(camera3_stream_configuration_t *stream_list);
     int processCaptureRequest(camera3_capture_request_t *request);
     void dump(int fd);
     int flush();
@@ -280,6 +281,7 @@
     QCamera3SupportChannel *mAnalysisChannel;
     QCamera3RawDumpChannel *mRawDumpChannel;
     QCamera3RegularChannel *mDummyBatchChannel;
+    QCameraPerfLock m_perfLock;
 
     void saveExifParams(metadata_buffer_t *metadata);
     mm_jpeg_exif_params_t mExifParams;
diff --git a/QCamera2/HAL3/QCamera3Stream.cpp b/QCamera2/HAL3/QCamera3Stream.cpp
index b49a4fa..d495748 100644
--- a/QCamera2/HAL3/QCamera3Stream.cpp
+++ b/QCamera2/HAL3/QCamera3Stream.cpp
@@ -39,7 +39,6 @@
 using namespace android;
 
 namespace qcamera {
-#define NUM_BATCH_BUFS   12
 #define MAX_BATCH_SIZE   32
 
 /*===========================================================================
@@ -236,7 +235,7 @@
         mBufDefs(NULL),
         mChannel(channel),
         mBatchSize(0),
-        mNumBatchBufs(NUM_BATCH_BUFS),
+        mNumBatchBufs(0),
         mStreamBatchBufs(NULL),
         mBatchBufDefs(NULL),
         mCurrentBatchBufDef(NULL),
@@ -373,12 +372,14 @@
         mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
         //mStreamInfo->num_of_burst = reprocess_config->offline.num_of_bufs;
         mStreamInfo->num_of_burst = 1;
-        ALOGI("%s: num_of_burst is %d", __func__, mStreamInfo->num_of_burst);
     } else if (batchSize) {
         if (batchSize > MAX_BATCH_SIZE) {
             ALOGE("%s: batchSize:%d is very large", __func__, batchSize);
+            rc = BAD_VALUE;
+            goto err4;
         }
         else {
+            mNumBatchBufs = MAX_INFLIGHT_HFR_REQUESTS / batchSize;
             mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
             mStreamInfo->user_buf_info.frame_buf_cnt = batchSize;
             mStreamInfo->user_buf_info.size =
@@ -1398,7 +1399,7 @@
 {
     int32_t rc = NO_ERROR;
     mm_camera_super_buf_t *frame;
-    mm_camera_buf_def_t* batchBuf;
+    mm_camera_buf_def_t batchBuf;
 
     if (LIKELY(!mBatchSize)) {
         ALOGE("%s: Stream: %d not in batch mode, but batch buffer received",
@@ -1414,15 +1415,23 @@
         return BAD_VALUE;
     }
 
-    batchBuf = superBuf->bufs[0];
+    /* Copy the batch buffer to local and queue the batch buffer to  empty queue
+     * to handle the new requests received while callbacks are in progress */
+    batchBuf = *superBuf->bufs[0];
+    if (!mFreeBatchBufQ.enqueue((void*) superBuf->bufs[0])) {
+        ALOGE("%s: batchBuf.buf_idx: %d enqueue failed", __func__,
+                batchBuf.buf_idx);
+        free(superBuf);
+        return NO_MEMORY;
+    }
     CDBG("%s: Received batch buffer: %d bufs_used: %d", __func__,
-            batchBuf->buf_idx, batchBuf->user_buf.bufs_used);
+            batchBuf.buf_idx, batchBuf.user_buf.bufs_used);
     //dummy local bufDef to issue multiple callbacks
     mm_camera_buf_def_t buf;
     memset(&buf, 0, sizeof(mm_camera_buf_def_t));
 
-    for (size_t i = 0; i < batchBuf->user_buf.bufs_used; i++) {
-        int32_t buf_idx = batchBuf->user_buf.buf_idx[i];
+    for (size_t i = 0; i < batchBuf.user_buf.bufs_used; i++) {
+        int32_t buf_idx = batchBuf.user_buf.buf_idx[i];
         buf = mBufDefs[buf_idx];
 
         /* this memory is freed inside dataCB. Should not be freed here */
@@ -1438,12 +1447,8 @@
             mDataCB(frame, this, mUserData);
         }
     }
-    CDBG("%s: batch buffer: %d callbacks done. Add to empty queue", __func__,
-            batchBuf->buf_idx);
-    if (!mFreeBatchBufQ.enqueue((void*) batchBuf)) {
-        ALOGE("%s: batchBuf->buf_idx: %d enqueue failed", __func__,
-                batchBuf->buf_idx);
-    }
+    CDBG("%s: batch buffer: %d callbacks done", __func__,
+            batchBuf.buf_idx);
 
     free(superBuf);
     return rc;
diff --git a/QCamera2/stack/common/cam_types.h b/QCamera2/stack/common/cam_types.h
index ccad567..a5efc5b 100644
--- a/QCamera2/stack/common/cam_types.h
+++ b/QCamera2/stack/common/cam_types.h
@@ -106,6 +106,8 @@
 #define MAX_INFLIGHT_REQUESTS  6
 #define MIN_INFLIGHT_REQUESTS  3
 #define MAX_INFLIGHT_REPROCESS_REQUESTS 1
+#define MAX_INFLIGHT_HFR_REQUESTS (48)
+#define MIN_INFLIGHT_HFR_REQUESTS (40)
 
 #define QCAMERA_DUMP_FRM_LOCATION "/data/misc/camera/"
 #define QCAMERA_MAX_FILEPATH_LENGTH 64
diff --git a/QCamera2/util/QCameraPerf.cpp b/QCamera2/util/QCameraPerf.cpp
new file mode 100644
index 0000000..399a97c
--- /dev/null
+++ b/QCamera2/util/QCameraPerf.cpp
@@ -0,0 +1,262 @@
+/* Copyright (c) 2015, 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 "QCameraPerf"
+
+#include <cutils/properties.h>
+#include <stdlib.h>
+#include <utils/Log.h>
+#include "QCameraPerf.h"
+
+#ifdef CDBG
+#undef CDBG
+#endif //#ifdef CDBG
+#define CDBG(fmt, args...) ALOGD_IF(gCamHalLogLevel >= 2, fmt, ##args)
+
+#ifdef CDBG_HIGH
+#undef CDBG_HIGH
+#endif //#ifdef CDBG_HIGH
+#define CDBG_HIGH(fmt, args...) ALOGD_IF(gCamHalLogLevel >= 1, fmt, ##args)
+
+
+namespace qcamera {
+
+extern volatile uint32_t gCamHalLogLevel;
+
+/*===========================================================================
+ * FUNCTION   : QCameraPerfLock constructor
+ *
+ * DESCRIPTION: initialize member variables
+ *
+ * PARAMETERS :
+ *   None
+ *
+ * RETURN     : void
+ *
+ *==========================================================================*/
+QCameraPerfLock::QCameraPerfLock() :
+        perf_lock_acq(NULL),
+        perf_lock_rel(NULL),
+        mDlHandle(NULL),
+        mPerfLockEnable(0),
+        mPerfLockHandle(-1)
+{
+}
+
+/*===========================================================================
+ * FUNCTION   : QCameraPerfLock destructor
+ *
+ * DESCRIPTION: class desctructor
+ *
+ * PARAMETERS :
+ *   None
+ *
+ * RETURN     : void
+ *
+ *==========================================================================*/
+QCameraPerfLock::~QCameraPerfLock()
+{
+    lock_deinit();
+}
+
+
+/*===========================================================================
+ * FUNCTION   : lock_init
+ *
+ * DESCRIPTION: opens the performance lib and initilizes the perf lock functions
+ *
+ * PARAMETERS :
+ *   None
+ *
+ * RETURN     : void
+ *
+ *==========================================================================*/
+void QCameraPerfLock::lock_init()
+{
+    const char *rc;
+    char value[PROPERTY_VALUE_MAX];
+    int len;
+
+    CDBG("%s E", __func__);
+    Mutex::Autolock lock(mLock);
+
+    property_get("persist.camera.perflock.enable", value, "1");
+    mPerfLockEnable = atoi(value);
+
+    if (mPerfLockEnable) {
+        perf_lock_acq = NULL;
+        perf_lock_rel = NULL;
+        mPerfLockHandle = -1;
+        /* Retrieve name of vendor extension library */
+        if (property_get("ro.vendor.extension_library", value, NULL) <= 0) {
+            goto cleanup;
+        }
+
+        mDlHandle = dlopen(value, RTLD_NOW | RTLD_LOCAL);
+        if (mDlHandle == NULL) {
+            goto cleanup;
+        }
+
+        dlerror();
+
+        perf_lock_acq = (int (*) (int, int, int[], int))dlsym(mDlHandle, "perf_lock_acq");
+        if ((rc = dlerror()) != NULL) {
+            ALOGE("failed to perf_lock_acq function handle");
+            goto cleanup;
+        }
+
+        perf_lock_rel = (int (*) (int))dlsym(mDlHandle, "perf_lock_rel");
+        if ((rc = dlerror()) != NULL) {
+            ALOGE("failed to perf_lock_rel function handle");
+            goto cleanup;
+        }
+        CDBG("%s X", __func__);
+        return;
+
+cleanup:
+        perf_lock_acq  = NULL;
+        perf_lock_rel  = NULL;
+        mPerfLockEnable = 0;
+        if (mDlHandle) {
+            dlclose(mDlHandle);
+            mDlHandle = NULL;
+        }
+    }
+    CDBG("%s X", __func__);
+}
+
+/*===========================================================================
+ * FUNCTION   : lock_deinit
+ *
+ * DESCRIPTION: deinitialize the perf lock parameters
+ *
+ * PARAMETERS :
+ *   None
+ *
+ * RETURN     : void
+ *
+ *==========================================================================*/
+void QCameraPerfLock::lock_deinit()
+{
+    Mutex::Autolock lock(mLock);
+    if (mPerfLockEnable) {
+        CDBG("%s E", __func__);
+        if (mDlHandle) {
+            perf_lock_acq  = NULL;
+            perf_lock_rel  = NULL;
+
+            dlclose(mDlHandle);
+            mDlHandle       = NULL;
+        }
+        mPerfLockEnable = 0;
+        CDBG("%s X", __func__);
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : lock_acq
+ *
+ * DESCRIPTION: acquire the performance lock
+ *
+ * PARAMETERS :
+ *   None
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *
+ *==========================================================================*/
+int32_t QCameraPerfLock::lock_acq()
+{
+    int32_t ret = -1;
+
+    CDBG("%s E", __func__);
+    Mutex::Autolock lock(mLock);
+
+    if (mPerfLockEnable) {
+        int32_t perf_lock_params[] = {
+                ALL_CPUS_PWR_CLPS_DIS,
+                CPU0_MIN_FREQ_TURBO_MAX,
+                CPU4_MIN_FREQ_TURBO_MAX
+        };
+        if ((NULL != perf_lock_acq) && (mPerfLockHandle < 0)) {
+            ret = (*perf_lock_acq)(mPerfLockHandle, ONE_SEC, perf_lock_params,
+                    sizeof(perf_lock_params) / sizeof(int32_t));
+            CDBG("%s ret %d", __func__, ret);
+            if (ret < 0) {
+                ALOGE("failed to acquire lock");
+            } else {
+                mPerfLockHandle = ret;
+            }
+        }
+        CDBG("%s perf_handle_acq %d ",__func__, mPerfLockHandle);
+    }
+
+    CDBG("%s X", __func__);
+    return ret;
+}
+
+/*===========================================================================
+ * FUNCTION   : lock_rel
+ *
+ * DESCRIPTION: release the performance lock
+ *
+ * PARAMETERS :
+ *   None
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *
+ *==========================================================================*/
+int32_t QCameraPerfLock::lock_rel()
+{
+    int ret = -1;
+    Mutex::Autolock lock(mLock);
+    if (mPerfLockEnable) {
+        CDBG("%s E", __func__);
+        if (mPerfLockHandle < 0) {
+            ALOGE("Error: mPerfLockHandle < 0,check if lock is acquired");
+            return ret;
+        }
+        CDBG("%s perf_handle_rel %d ",__func__, mPerfLockHandle);
+
+        if ((NULL != perf_lock_rel) && (0 <= mPerfLockHandle)) {
+            ret = (*perf_lock_rel)(mPerfLockHandle);
+            if (ret < 0) {
+                ALOGE("failed to release lock");
+            }
+            mPerfLockHandle = -1;
+        }
+        CDBG("%s X", __func__);
+    }
+    return ret;
+}
+
+}; // namespace qcamera
diff --git a/QCamera2/util/QCameraPerf.h b/QCamera2/util/QCameraPerf.h
new file mode 100644
index 0000000..6ff78ec
--- /dev/null
+++ b/QCamera2/util/QCameraPerf.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2015, The Linux Foundataion. 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.
+ *
+ */
+
+#ifndef __QCAMERAPERF_H__
+#define __QCAMERAPERF_H__
+
+#include <dlfcn.h>
+#include <utils/Mutex.h>
+
+#define ONE_SEC 1000
+
+typedef enum {
+    ALL_CPUS_PWR_CLPS_DIS = 0x101,
+    CPU0_MIN_FREQ_TURBO_MAX = 0x2FE,
+    CPU4_MIN_FREQ_TURBO_MAX = 0x1FFE,
+}perf_lock_params_t;
+
+using namespace android;
+
+namespace qcamera {
+
+class QCameraPerfLock {
+public:
+    QCameraPerfLock();
+    ~QCameraPerfLock();
+
+    void    lock_init();
+    void    lock_deinit();
+    int32_t lock_rel();
+    int32_t lock_acq();
+private:
+    int32_t        (*perf_lock_acq)(int, int, int[], int);
+    int32_t        (*perf_lock_rel)(int);
+    void           *mDlHandle;
+    uint32_t        mPerfLockEnable;
+    Mutex           mLock;
+    int32_t         mPerfLockHandle;  // Performance lock library handle
+};
+
+}; // namespace qcamera
+
+#endif /* __QCAMREAPERF_H__ */