aboutsummaryrefslogtreecommitdiff
path: root/camera/QCamera2/util
diff options
context:
space:
mode:
authorPrateek Chaubey <chaubeyprateek@gmail.com>2018-01-07 20:55:14 +0530
committerDavide Garberi <dade.garberi@gmail.com>2018-01-19 14:09:15 +0100
commit6616278131edd80a12545085e06ee6b0e0a0a788 (patch)
tree0aef88ed11809a9d67f6abe4dc2ff782a14737e2 /camera/QCamera2/util
parentcc4ccf34871da343111bf68d16ba4e4c67cac1dc (diff)
msm8996-common: zuk: Import OSS Camera HAL
Tag: LA.HB.1.3.2-32600-8x96.0 Signed-off-by: Davide Garberi <dade.garberi@gmail.com>
Diffstat (limited to 'camera/QCamera2/util')
-rw-r--r--camera/QCamera2/util/QCameraBufferMaps.cpp246
-rw-r--r--camera/QCamera2/util/QCameraBufferMaps.h80
-rw-r--r--camera/QCamera2/util/QCameraCmdThread.cpp225
-rw-r--r--camera/QCamera2/util/QCameraCmdThread.h76
-rw-r--r--camera/QCamera2/util/QCameraCommon.cpp226
-rw-r--r--camera/QCamera2/util/QCameraCommon.h61
-rw-r--r--camera/QCamera2/util/QCameraDisplay.cpp282
-rw-r--r--camera/QCamera2/util/QCameraDisplay.h76
-rw-r--r--camera/QCamera2/util/QCameraFlash.cpp413
-rw-r--r--camera/QCamera2/util/QCameraFlash.h69
-rw-r--r--camera/QCamera2/util/QCameraPerf.cpp545
-rw-r--r--camera/QCamera2/util/QCameraPerf.h93
-rw-r--r--camera/QCamera2/util/QCameraQueue.cpp464
-rw-r--r--camera/QCamera2/util/QCameraQueue.h79
-rw-r--r--camera/QCamera2/util/QCameraTrace.h150
15 files changed, 3085 insertions, 0 deletions
diff --git a/camera/QCamera2/util/QCameraBufferMaps.cpp b/camera/QCamera2/util/QCameraBufferMaps.cpp
new file mode 100644
index 0000000..d7c058e
--- /dev/null
+++ b/camera/QCamera2/util/QCameraBufferMaps.cpp
@@ -0,0 +1,246 @@
+/* Copyright (c) 2015-2016, 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 "QCameraBufferMaps"
+
+// System dependencies
+#include <utils/Errors.h>
+#include <stdlib.h>
+#include <string.h>
+
+// Camera dependencies
+#include "QCameraBufferMaps.h"
+
+using namespace android;
+
+namespace qcamera {
+
+/*===========================================================================
+ * FUNCTION : QCameraBufferMaps
+ *
+ * DESCRIPTION: default constructor of QCameraBufferMaps
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraBufferMaps::QCameraBufferMaps()
+{
+ memset(&mBufMapList, 0, sizeof(mBufMapList));
+}
+
+/*===========================================================================
+ * FUNCTION : QCameraBufferMaps
+ *
+ * DESCRIPTION: copy constructor of QCameraBufferMaps
+ *
+ * PARAMETERS :
+ * @pBufferMaps : object to be copied
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraBufferMaps::QCameraBufferMaps(const QCameraBufferMaps& pBufferMaps)
+{
+ memcpy(&mBufMapList, &pBufferMaps.mBufMapList, sizeof(mBufMapList));
+}
+
+/*===========================================================================
+ * FUNCTION : QCameraBufferMaps
+ *
+ * DESCRIPTION: constructor of QCameraBufferMaps
+ *
+ * PARAMETERS :
+ * @pBufMapList : list of buffer maps
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraBufferMaps::QCameraBufferMaps(const cam_buf_map_type_list& pBufMapList)
+{
+ memcpy(&mBufMapList, &pBufMapList, sizeof(mBufMapList));
+}
+
+/*===========================================================================
+ * FUNCTION : QCameraBufferMaps
+ *
+ * DESCRIPTION: constructor of QCameraBufferMaps
+ *
+ * PARAMETERS :
+ * @pType : Type of buffer
+ * @pStreamId : Stream id
+ * @pFrameIndex : Frame index
+ * @pPlaneIndex : Plane index
+ * @pCookie : Could be job_id to identify mapping job
+ * @pFd : Origin file descriptor
+ * @pSize : Size of the buffer
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraBufferMaps::QCameraBufferMaps(cam_mapping_buf_type pType,
+ uint32_t pStreamId,
+ uint32_t pFrameIndex,
+ int32_t pPlaneIndex,
+ uint32_t pCookie,
+ int32_t pFd,
+ size_t pSize)
+{
+ memset(&mBufMapList, 0, sizeof(mBufMapList));
+ enqueue(pType, pStreamId, pFrameIndex, pPlaneIndex, pCookie, pFd, pSize);
+}
+
+/*===========================================================================
+ * FUNCTION : ~QCameraBufferMaps
+ *
+ * DESCRIPTION: destructor of QCameraBufferMaps
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraBufferMaps::~QCameraBufferMaps()
+{
+}
+
+/*===========================================================================
+ * FUNCTION : operator=
+ *
+ * DESCRIPTION: assignment operator of QCameraBufferMaps
+ *
+ * PARAMETERS :
+ * @pBufferMaps : object to be copied
+ *
+ * RETURN : *this, with updated contents
+ *==========================================================================*/
+QCameraBufferMaps& QCameraBufferMaps::operator=(const QCameraBufferMaps& pBufferMaps)
+{
+ if (&pBufferMaps != this) {
+ memcpy(&mBufMapList, &pBufferMaps.mBufMapList, sizeof(mBufMapList));
+ }
+ return *this;
+}
+
+/*===========================================================================
+ * FUNCTION : enqueue
+ *
+ * DESCRIPTION: Add a buffer map
+ *
+ * PARAMETERS :
+ * @pType : Type of buffer
+ * @pStreamId : Stream id
+ * @pFrameIndex : Frame index
+ * @pPlaneIndex : Plane index
+ * @pCookie : Could be job_id to identify mapping job
+ * @pFd : Origin file descriptor
+ * @pSize : Size of the buffer
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+uint32_t QCameraBufferMaps::enqueue(cam_mapping_buf_type pType,
+ uint32_t pStreamId,
+ uint32_t pFrameIndex,
+ int32_t pPlaneIndex,
+ uint32_t pCookie,
+ int32_t pFd,
+ size_t pSize)
+{
+ uint32_t pos = mBufMapList.length++;
+ mBufMapList.buf_maps[pos].type = pType;
+ mBufMapList.buf_maps[pos].stream_id = pStreamId;
+ mBufMapList.buf_maps[pos].frame_idx = pFrameIndex;
+ mBufMapList.buf_maps[pos].plane_idx = pPlaneIndex;
+ mBufMapList.buf_maps[pos].cookie = pCookie;
+ mBufMapList.buf_maps[pos].fd = pFd;
+ mBufMapList.buf_maps[pos].size = pSize;
+
+ return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION : getCamBufMapList
+ *
+ * DESCRIPTION: Populate the list
+ *
+ * PARAMETERS :
+ * @pBufMapList : [output] the list of buffer maps
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+uint32_t QCameraBufferMaps::getCamBufMapList(cam_buf_map_type_list& pBufMapList) const
+{
+ memcpy(&pBufMapList, &mBufMapList, sizeof(pBufMapList));
+
+ return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION : makeSingletonBufMapList
+ *
+ * DESCRIPTION: Create a buffer map list of a single element
+ *
+ * PARAMETERS :
+ * @pType : Type of buffer
+ * @pStreamId : Stream id
+ * @pFrameIndex : Frame index
+ * @pPlaneIndex : Plane index
+ * @pCookie : Could be job_id to identify mapping job
+ * @pFd : Origin file descriptor
+ * @pSize : Size of the buffer
+ * @pBufMapList : [output] the list of buffer maps
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+uint32_t QCameraBufferMaps::makeSingletonBufMapList(cam_mapping_buf_type pType,
+ uint32_t pStreamId,
+ uint32_t pFrameIndex,
+ int32_t pPlaneIndex,
+ uint32_t pCookie,
+ int32_t pFd,
+ size_t pSize,
+ cam_buf_map_type_list& pBufMapList)
+{
+ uint32_t rc = NO_ERROR;
+
+ QCameraBufferMaps bufferMaps(pType,
+ pStreamId,
+ pFrameIndex,
+ pPlaneIndex,
+ pCookie,
+ pFd,
+ pSize);
+ rc = bufferMaps.getCamBufMapList(pBufMapList);
+
+ return rc;
+}
+
+}; // namespace qcamera
diff --git a/camera/QCamera2/util/QCameraBufferMaps.h b/camera/QCamera2/util/QCameraBufferMaps.h
new file mode 100644
index 0000000..eaa4707
--- /dev/null
+++ b/camera/QCamera2/util/QCameraBufferMaps.h
@@ -0,0 +1,80 @@
+/* Copyright (c) 2015-2016, 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.
+ *
+ */
+
+#ifndef __QCAMERA_BUFFERMAPS_H__
+#define __QCAMERA_BUFFERMAPS_H__
+
+// Camera dependencies
+#include "cam_types.h"
+
+namespace qcamera {
+
+class QCameraBufferMaps {
+public:
+ QCameraBufferMaps();
+ QCameraBufferMaps(const QCameraBufferMaps& pBufferMaps);
+ QCameraBufferMaps(const cam_buf_map_type_list& pBufMapList);
+ QCameraBufferMaps(cam_mapping_buf_type pType,
+ uint32_t pStreamId,
+ uint32_t pFrameIndex,
+ int32_t pPlaneIndex,
+ uint32_t pCookie,
+ int32_t pFd,
+ size_t pSize);
+
+ ~QCameraBufferMaps();
+
+ QCameraBufferMaps& operator=(const QCameraBufferMaps& pBufferMaps);
+
+ uint32_t enqueue(cam_mapping_buf_type pType,
+ uint32_t pStreamId,
+ uint32_t pFrameIndex,
+ int32_t pPlaneIndex,
+ uint32_t pCookie,
+ int32_t pFd,
+ size_t pSize);
+
+ uint32_t getCamBufMapList(cam_buf_map_type_list& pBufMapList) const;
+
+ static uint32_t makeSingletonBufMapList(cam_mapping_buf_type pType,
+ uint32_t pStreamId,
+ uint32_t pFrameIndex,
+ int32_t pPlaneIndex,
+ uint32_t pCookie,
+ int32_t pFd,
+ size_t pSize,
+ cam_buf_map_type_list& pBufMapList);
+
+private:
+ cam_buf_map_type_list mBufMapList;
+};
+
+}; // namespace qcamera
+#endif /* __QCAMERA_BUFFERMAPS_H__ */
+
diff --git a/camera/QCamera2/util/QCameraCmdThread.cpp b/camera/QCamera2/util/QCameraCmdThread.cpp
new file mode 100644
index 0000000..8b191b0
--- /dev/null
+++ b/camera/QCamera2/util/QCameraCmdThread.cpp
@@ -0,0 +1,225 @@
+/* Copyright (c) 2012-2016, 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.
+*
+*/
+
+// System dependencies
+#include <string.h>
+#include <utils/Errors.h>
+#define PRCTL_H <SYSTEM_HEADER_PREFIX/prctl.h>
+#include PRCTL_H
+
+// Camera dependencies
+#include "QCameraCmdThread.h"
+
+extern "C" {
+#include "mm_camera_dbg.h"
+}
+
+using namespace android;
+
+namespace qcamera {
+
+/*===========================================================================
+ * FUNCTION : QCameraCmdThread
+ *
+ * DESCRIPTION: default constructor of QCameraCmdThread
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraCmdThread::QCameraCmdThread() :
+ cmd_queue()
+{
+ cmd_pid = 0;
+ cam_sem_init(&sync_sem, 0);
+ cam_sem_init(&cmd_sem, 0);
+}
+
+/*===========================================================================
+ * FUNCTION : ~QCameraCmdThread
+ *
+ * DESCRIPTION: deconstructor of QCameraCmdThread
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraCmdThread::~QCameraCmdThread()
+{
+ exit();
+ cam_sem_destroy(&sync_sem);
+ cam_sem_destroy(&cmd_sem);
+}
+
+/*===========================================================================
+ * FUNCTION : launch
+ *
+ * DESCRIPTION: launch Cmd Thread
+ *
+ * PARAMETERS :
+ * @start_routine : thread routine function ptr
+ * @user_data : user data ptr
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCameraCmdThread::launch(void *(*start_routine)(void *),
+ void* user_data)
+{
+ /* launch the thread */
+ pthread_create(&cmd_pid,
+ NULL,
+ start_routine,
+ user_data);
+ return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION : setName
+ *
+ * DESCRIPTION: name the cmd thread
+ *
+ * PARAMETERS :
+ * @name : desired name for the thread
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCameraCmdThread::setName(const char* name)
+{
+ /* name the thread */
+ prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
+ return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION : sendCmd
+ *
+ * DESCRIPTION: send a command to the Cmd Thread
+ *
+ * PARAMETERS :
+ * @cmd : command to be executed.
+ * @sync_cmd: flag to indicate if this is a synchorinzed cmd. If true, this call
+ * will wait until signal is set after the command is completed.
+ * @priority: flag to indicate if this is a cmd with priority. If true, the cmd
+ * will be enqueued to the head with priority.
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCameraCmdThread::sendCmd(camera_cmd_type_t cmd, uint8_t sync_cmd, uint8_t priority)
+{
+ camera_cmd_t *node = (camera_cmd_t *)malloc(sizeof(camera_cmd_t));
+ if (NULL == node) {
+ LOGE("No memory for camera_cmd_t");
+ return NO_MEMORY;
+ }
+ memset(node, 0, sizeof(camera_cmd_t));
+ node->cmd = cmd;
+
+ if (priority) {
+ if (!cmd_queue.enqueueWithPriority((void *)node)) {
+ free(node);
+ node = NULL;
+ }
+ } else {
+ if (!cmd_queue.enqueue((void *)node)) {
+ free(node);
+ node = NULL;
+ }
+ }
+ cam_sem_post(&cmd_sem);
+
+ /* if is a sync call, need to wait until it returns */
+ if (sync_cmd) {
+ cam_sem_wait(&sync_sem);
+ }
+ return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION : getCmd
+ *
+ * DESCRIPTION: dequeue a cmommand from cmd queue
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : cmd dequeued
+ *==========================================================================*/
+camera_cmd_type_t QCameraCmdThread::getCmd()
+{
+ camera_cmd_type_t cmd = CAMERA_CMD_TYPE_NONE;
+ camera_cmd_t *node = (camera_cmd_t *)cmd_queue.dequeue();
+ if (NULL == node) {
+ LOGD("No notify avail");
+ return CAMERA_CMD_TYPE_NONE;
+ } else {
+ cmd = node->cmd;
+ free(node);
+ }
+ return cmd;
+}
+
+/*===========================================================================
+ * FUNCTION : exit
+ *
+ * DESCRIPTION: exit the CMD thread
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCameraCmdThread::exit()
+{
+ int32_t rc = NO_ERROR;
+
+ if (cmd_pid == 0) {
+ return rc;
+ }
+
+ rc = sendCmd(CAMERA_CMD_TYPE_EXIT, 0, 1);
+ if (NO_ERROR != rc) {
+ LOGE("Error during exit, rc = %d", rc);
+ return rc;
+ }
+
+ /* wait until cmd thread exits */
+ if (pthread_join(cmd_pid, NULL) != 0) {
+ LOGD("pthread dead already\n");
+ }
+ cmd_pid = 0;
+ return rc;
+}
+
+}; // namespace qcamera
diff --git a/camera/QCamera2/util/QCameraCmdThread.h b/camera/QCamera2/util/QCameraCmdThread.h
new file mode 100644
index 0000000..b0764b6
--- /dev/null
+++ b/camera/QCamera2/util/QCameraCmdThread.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2012, 2016, 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.
+ *
+ */
+
+#ifndef __QCAMERA_CMD_THREAD_H__
+#define __QCAMERA_CMD_THREAD_H__
+
+// System dependencies
+#include <pthread.h>
+
+// Camera dependencies
+#include "cam_semaphore.h"
+#include "cam_types.h"
+#include "QCameraQueue.h"
+
+namespace qcamera {
+
+typedef enum
+{
+ CAMERA_CMD_TYPE_NONE,
+ CAMERA_CMD_TYPE_START_DATA_PROC,
+ CAMERA_CMD_TYPE_STOP_DATA_PROC,
+ CAMERA_CMD_TYPE_DO_NEXT_JOB,
+ CAMERA_CMD_TYPE_EXIT,
+ CAMERA_CMD_TYPE_MAX
+} camera_cmd_type_t;
+
+typedef struct {
+ camera_cmd_type_t cmd;
+} camera_cmd_t;
+
+class QCameraCmdThread {
+public:
+ QCameraCmdThread();
+ ~QCameraCmdThread();
+
+ int32_t launch(void *(*start_routine)(void *), void* user_data);
+ int32_t setName(const char* name);
+ int32_t exit();
+ int32_t sendCmd(camera_cmd_type_t cmd, uint8_t sync_cmd, uint8_t priority);
+ camera_cmd_type_t getCmd();
+
+ QCameraQueue cmd_queue; /* cmd queue */
+ pthread_t cmd_pid; /* cmd thread ID */
+ cam_semaphore_t cmd_sem; /* semaphore for cmd thread */
+ cam_semaphore_t sync_sem; /* semaphore for synchronized call signal */
+};
+
+}; // namespace qcamera
+
+#endif /* __QCAMERA_CMD_THREAD_H__ */
diff --git a/camera/QCamera2/util/QCameraCommon.cpp b/camera/QCamera2/util/QCameraCommon.cpp
new file mode 100644
index 0000000..0cc2654
--- /dev/null
+++ b/camera/QCamera2/util/QCameraCommon.cpp
@@ -0,0 +1,226 @@
+/* Copyright (c) 2016, 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 "QCameraCommon"
+
+// System dependencies
+#include <utils/Errors.h>
+#include <stdlib.h>
+#include <string.h>
+#include <utils/Log.h>
+
+// Camera dependencies
+#include "QCameraCommon.h"
+
+using namespace android;
+
+namespace qcamera {
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/*===========================================================================
+ * FUNCTION : QCameraCommon
+ *
+ * DESCRIPTION: default constructor of QCameraCommon
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraCommon::QCameraCommon() :
+ m_pCapability(NULL)
+{
+}
+
+/*===========================================================================
+ * FUNCTION : ~QCameraCommon
+ *
+ * DESCRIPTION: destructor of QCameraCommon
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraCommon::~QCameraCommon()
+{
+}
+
+/*===========================================================================
+ * FUNCTION : init
+ *
+ * DESCRIPTION: Init function for QCameraCommon
+ *
+ * PARAMETERS :
+ * @pCapability : Capabilities
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCameraCommon::init(cam_capability_t *pCapability)
+{
+ m_pCapability = pCapability;
+
+ return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION : calculateLCM
+ *
+ * DESCRIPTION: Get the LCM of 2 numbers
+ *
+ * PARAMETERS :
+ * @num1 : First number
+ * @num2 : second number
+ *
+ * RETURN : int32_t type (LCM)
+ *
+ *==========================================================================*/
+uint32_t QCameraCommon::calculateLCM(int32_t num1, int32_t num2)
+{
+ uint32_t lcm = 0;
+ uint32_t temp = 0;
+
+ if ((num1 < 1) && (num2 < 1)) {
+ return 0;
+ } else if (num1 < 1) {
+ return num2;
+ } else if (num2 < 1) {
+ return num1;
+ }
+
+ if (num1 > num2) {
+ lcm = num1;
+ } else {
+ lcm = num2;
+ }
+ temp = lcm;
+
+ while (1) {
+ if (((lcm % num1) == 0) && ((lcm % num2) == 0)) {
+ break;
+ }
+ lcm += temp;
+ }
+ return lcm;
+}
+
+/*===========================================================================
+ * FUNCTION : getAnalysisInfo
+ *
+ * DESCRIPTION: Get the Analysis information based on
+ * current mode and feature mask
+ *
+ * PARAMETERS :
+ * @fdVideoEnabled : Whether fdVideo enabled currently
+ * @hal3 : Whether hal3 or hal1
+ * @featureMask : Feature mask
+ * @pAnalysis_info : Analysis info to be filled
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCameraCommon::getAnalysisInfo(
+ bool fdVideoEnabled,
+ bool hal3,
+ cam_feature_mask_t featureMask,
+ cam_analysis_info_t *pAnalysisInfo)
+{
+ if (!pAnalysisInfo) {
+ return BAD_VALUE;
+ }
+
+ pAnalysisInfo->valid = 0;
+
+ if ((fdVideoEnabled == TRUE) && (hal3 == FALSE) &&
+ (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO].hw_analysis_supported) &&
+ (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO].valid)) {
+ *pAnalysisInfo =
+ m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO];
+ } else if (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_STILL].valid) {
+ *pAnalysisInfo =
+ m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_STILL];
+ if (hal3 == TRUE) {
+ pAnalysisInfo->analysis_max_res = pAnalysisInfo->analysis_recommended_res;
+ }
+ }
+
+ if ((featureMask & CAM_QCOM_FEATURE_PAAF) &&
+ (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_PAAF].valid)) {
+ cam_analysis_info_t *pPaafInfo =
+ &m_pCapability->analysis_info[CAM_ANALYSIS_INFO_PAAF];
+
+ if (!pAnalysisInfo->valid) {
+ *pAnalysisInfo = *pPaafInfo;
+ } else {
+ pAnalysisInfo->analysis_max_res.width =
+ MAX(pAnalysisInfo->analysis_max_res.width,
+ pPaafInfo->analysis_max_res.width);
+ pAnalysisInfo->analysis_max_res.height =
+ MAX(pAnalysisInfo->analysis_max_res.height,
+ pPaafInfo->analysis_max_res.height);
+ pAnalysisInfo->analysis_padding_info.height_padding =
+ calculateLCM(pAnalysisInfo->analysis_padding_info.height_padding,
+ pPaafInfo->analysis_padding_info.height_padding);
+ pAnalysisInfo->analysis_padding_info.width_padding =
+ calculateLCM(pAnalysisInfo->analysis_padding_info.width_padding,
+ pPaafInfo->analysis_padding_info.width_padding);
+ pAnalysisInfo->analysis_padding_info.plane_padding =
+ calculateLCM(pAnalysisInfo->analysis_padding_info.plane_padding,
+ pPaafInfo->analysis_padding_info.plane_padding);
+ pAnalysisInfo->analysis_padding_info.min_stride =
+ MAX(pAnalysisInfo->analysis_padding_info.min_stride,
+ pPaafInfo->analysis_padding_info.min_stride);
+ pAnalysisInfo->analysis_padding_info.min_stride =
+ ALIGN(pAnalysisInfo->analysis_padding_info.min_stride,
+ pAnalysisInfo->analysis_padding_info.width_padding);
+
+ pAnalysisInfo->analysis_padding_info.min_scanline =
+ MAX(pAnalysisInfo->analysis_padding_info.min_scanline,
+ pPaafInfo->analysis_padding_info.min_scanline);
+ pAnalysisInfo->analysis_padding_info.min_scanline =
+ ALIGN(pAnalysisInfo->analysis_padding_info.min_scanline,
+ pAnalysisInfo->analysis_padding_info.height_padding);
+
+ pAnalysisInfo->hw_analysis_supported |=
+ pPaafInfo->hw_analysis_supported;
+ }
+ }
+
+ return pAnalysisInfo->valid ? NO_ERROR : BAD_VALUE;
+}
+
+}; // namespace qcamera
diff --git a/camera/QCamera2/util/QCameraCommon.h b/camera/QCamera2/util/QCameraCommon.h
new file mode 100644
index 0000000..844b087
--- /dev/null
+++ b/camera/QCamera2/util/QCameraCommon.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2016, 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.
+ *
+ */
+
+#ifndef __QCAMERA_COMMON_H__
+#define __QCAMERA_COMMON_H__
+
+// Camera dependencies
+#include "cam_types.h"
+#include "cam_intf.h"
+
+namespace qcamera {
+
+#define ALIGN(a, b) (((a) + (b)) & ~(b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+class QCameraCommon {
+public:
+ QCameraCommon();
+ ~QCameraCommon();
+
+ int32_t init(cam_capability_t *cap);
+
+ int32_t getAnalysisInfo(
+ bool fdVideoEnabled, bool hal3, cam_feature_mask_t featureMask,
+ cam_analysis_info_t *pAnalysisInfo);
+ static uint32_t calculateLCM(int32_t num1, int32_t num2);
+
+private:
+ cam_capability_t *m_pCapability;
+
+};
+
+}; // namespace qcamera
+#endif /* __QCAMERA_COMMON_H__ */
+
diff --git a/camera/QCamera2/util/QCameraDisplay.cpp b/camera/QCamera2/util/QCameraDisplay.cpp
new file mode 100644
index 0000000..108cc72
--- /dev/null
+++ b/camera/QCamera2/util/QCameraDisplay.cpp
@@ -0,0 +1,282 @@
+/* Copyright (c) 2015-2016, 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 "QCameraDisplay"
+
+// To remove
+#include <cutils/properties.h>
+
+// Camera dependencies
+#include "QCamera2HWI.h"
+#include "QCameraDisplay.h"
+
+extern "C" {
+#include "mm_camera_dbg.h"
+}
+
+#define CAMERA_VSYNC_WAIT_MS 33 // Used by vsync thread to wait for vsync timeout.
+#define DISPLAY_EVENT_RECEIVER_ARRAY_SIZE 1
+#define DISPLAY_DEFAULT_FPS 60
+
+namespace qcamera {
+
+/*===========================================================================
+ * FUNCTION : vsyncEventReceiverCamera
+ *
+ * DESCRIPTION: Computes average vsync interval. Called by display
+ * event handler for every vsync event.
+ *
+ * PARAMETERS :
+ * @fd : file descriptor
+ * @events : events
+ * @data : pointer to user data provided during call back registration.
+ *
+ * RETURN : always returns 1
+ *==========================================================================*/
+int QCameraDisplay::vsyncEventReceiverCamera(__unused int fd,
+ __unused int events, void* data) {
+ android::DisplayEventReceiver::Event buffer[DISPLAY_EVENT_RECEIVER_ARRAY_SIZE];
+ QCameraDisplay* pQCameraDisplay = (QCameraDisplay *) data;
+ ssize_t n;
+
+ while ((n = pQCameraDisplay->mDisplayEventReceiver.getEvents(buffer,
+ DISPLAY_EVENT_RECEIVER_ARRAY_SIZE)) > 0) {
+ for (int i = 0 ; i < n ; i++) {
+ if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
+ pQCameraDisplay->computeAverageVsyncInterval(buffer[i].header.timestamp);
+ }
+ }
+ }
+ return 1;
+}
+
+/*===========================================================================
+ * FUNCTION : vsyncThreadCamera
+ *
+ * DESCRIPTION: Thread registers a call back function for every vsync event
+ * waits on the looper for the next vsync.
+ *
+ * PARAMETERS :
+ * @data : receives vsync_info_t structure.
+ *
+ * RETURN : NULL.Just to fullfill the type requirement of thread function.
+ *==========================================================================*/
+void* QCameraDisplay::vsyncThreadCamera(void * data)
+{
+ QCameraDisplay* pQCameraDisplay = (QCameraDisplay *) data;
+ android::sp<Looper> looper;
+
+ looper = new android::Looper(false);
+ status_t status = pQCameraDisplay->mDisplayEventReceiver.initCheck();
+ if (status != NO_ERROR) {
+ LOGE("Initialization of DisplayEventReceiver failed with status: %d", status);
+ return NULL;
+ }
+ looper->addFd(pQCameraDisplay->mDisplayEventReceiver.getFd(), 0, ALOOPER_EVENT_INPUT,
+ QCameraDisplay::vsyncEventReceiverCamera, pQCameraDisplay);
+ pQCameraDisplay->mDisplayEventReceiver.setVsyncRate(1);
+ while(pQCameraDisplay->mThreadExit == 0)
+ {
+ looper->pollOnce(CAMERA_VSYNC_WAIT_MS);
+ }
+ return NULL;
+}
+
+/*===========================================================================
+ * FUNCTION : ~QCameraDisplay
+ *
+ * DESCRIPTION: constructor of QCameraDisplay
+ *
+ * PARAMETERS : none
+ *
+ * RETURN : none
+ *==========================================================================*/
+QCameraDisplay::QCameraDisplay()
+ : mVsyncTimeStamp(0),
+ mAvgVsyncInterval(0),
+ mOldTimeStamp(0),
+ mVsyncHistoryIndex(0),
+ mAdditionalVsyncOffsetForWiggle(0),
+ mThreadExit(0),
+ mNum_vsync_from_vfe_isr_to_presentation_timestamp(0),
+ mSet_timestamp_num_ms_prior_to_vsync(0),
+ mVfe_and_mdp_freq_wiggle_filter_max_ms(0),
+ mVfe_and_mdp_freq_wiggle_filter_min_ms(0)
+{
+ int rc = NO_ERROR;
+
+ memset(&mVsyncIntervalHistory, 0, sizeof(mVsyncIntervalHistory));
+ rc = pthread_create(&mVsyncThreadCameraHandle, NULL, vsyncThreadCamera, (void *)this);
+ if (rc == NO_ERROR) {
+ char value[PROPERTY_VALUE_MAX];
+ nsecs_t default_vsync_interval;
+ pthread_setname_np(mVsyncThreadCameraHandle, "CAM_Vsync_Thread");
+ // Read a list of properties used for tuning
+ property_get("persist.camera.disp.num_vsync", value, "4");
+ mNum_vsync_from_vfe_isr_to_presentation_timestamp = atoi(value);
+ property_get("persist.camera.disp.ms_to_vsync", value, "2");
+ mSet_timestamp_num_ms_prior_to_vsync = atoi(value);
+ property_get("persist.camera.disp.filter_max", value, "2");
+ mVfe_and_mdp_freq_wiggle_filter_max_ms = atoi(value);
+ property_get("persist.camera.disp.filter_min", value, "4");
+ mVfe_and_mdp_freq_wiggle_filter_min_ms = atoi(value);
+ property_get("persist.camera.disp.fps", value, "60");
+ if (atoi(value) > 0) {
+ default_vsync_interval= s2ns(1) / atoi(value);
+ } else {
+ default_vsync_interval= s2ns(1) / DISPLAY_DEFAULT_FPS;
+ }
+ for (int i=0; i < CAMERA_NUM_VSYNC_INTERVAL_HISTORY; i++) {
+ mVsyncIntervalHistory[i] = default_vsync_interval;
+ }
+ LOGD("display jitter num_vsync_from_vfe_isr_to_presentation_timestamp %u \
+ set_timestamp_num_ms_prior_to_vsync %u",
+ mNum_vsync_from_vfe_isr_to_presentation_timestamp,
+ mSet_timestamp_num_ms_prior_to_vsync);
+ LOGD("display jitter vfe_and_mdp_freq_wiggle_filter_max_ms %u \
+ vfe_and_mdp_freq_wiggle_filter_min_ms %u",
+ mVfe_and_mdp_freq_wiggle_filter_max_ms,
+ mVfe_and_mdp_freq_wiggle_filter_min_ms);
+ } else {
+ mVsyncThreadCameraHandle = 0;
+ }
+}
+
+/*===========================================================================
+ * FUNCTION : ~QCameraDisplay
+ *
+ * DESCRIPTION: destructor of QCameraDisplay
+ *
+ * PARAMETERS : none
+ *
+ * RETURN : none
+ *==========================================================================*/
+QCameraDisplay::~QCameraDisplay()
+{
+ mThreadExit = 1;
+ if (mVsyncThreadCameraHandle != 0) {
+ pthread_join(mVsyncThreadCameraHandle, NULL);
+ }
+}
+
+/*===========================================================================
+ * FUNCTION : computeAverageVsyncInterval
+ *
+ * DESCRIPTION: Computes average vsync interval using current and previously
+ * stored vsync data.
+ *
+ * PARAMETERS : current vsync time stamp
+ *
+ * RETURN : none
+ *==========================================================================*/
+void QCameraDisplay::computeAverageVsyncInterval(nsecs_t currentVsyncTimeStamp)
+{
+ nsecs_t sum;
+ nsecs_t vsyncMaxOutlier;
+ nsecs_t vsyncMinOutlier;
+
+ mVsyncTimeStamp = currentVsyncTimeStamp;
+ if (mOldTimeStamp) {
+ // Compute average vsync interval using current and previously stored vsync data.
+ // Leave the max and min vsync interval from history in computing the average.
+ mVsyncIntervalHistory[mVsyncHistoryIndex] = currentVsyncTimeStamp - mOldTimeStamp;
+ mVsyncHistoryIndex++;
+ mVsyncHistoryIndex = mVsyncHistoryIndex % CAMERA_NUM_VSYNC_INTERVAL_HISTORY;
+ sum = mVsyncIntervalHistory[0];
+ vsyncMaxOutlier = mVsyncIntervalHistory[0];
+ vsyncMinOutlier = mVsyncIntervalHistory[0];
+ for (int j=1; j<CAMERA_NUM_VSYNC_INTERVAL_HISTORY; j++) {
+ sum += mVsyncIntervalHistory[j];
+ if (vsyncMaxOutlier < mVsyncIntervalHistory[j]) {
+ vsyncMaxOutlier = mVsyncIntervalHistory[j];
+ } else if (vsyncMinOutlier > mVsyncIntervalHistory[j]) {
+ vsyncMinOutlier = mVsyncIntervalHistory[j];
+ }
+ }
+ sum = sum - vsyncMaxOutlier - vsyncMinOutlier;
+ mAvgVsyncInterval = sum / (CAMERA_NUM_VSYNC_INTERVAL_HISTORY - 2);
+ }
+ mOldTimeStamp = currentVsyncTimeStamp;
+}
+
+/*===========================================================================
+ * FUNCTION : computePresentationTimeStamp
+ *
+ * DESCRIPTION: Computes presentation time stamp using vsync interval
+ * and last vsync time stamp and few other tunable variables
+ * to place the time stamp at the expected future vsync
+ *
+ * PARAMETERS : current frame time stamp set by VFE when buffer copy done.
+ *
+ * RETURN : time stamp in future or 0 in case of failure.
+ *==========================================================================*/
+nsecs_t QCameraDisplay::computePresentationTimeStamp(nsecs_t frameTimeStamp)
+{
+ nsecs_t moveToNextVsync;
+ nsecs_t keepInCurrentVsync;
+ nsecs_t timeDifference = 0;
+ nsecs_t presentationTimeStamp = 0;
+ int expectedVsyncOffset = 0;
+ int vsyncOffset;
+
+ if ( (mAvgVsyncInterval != 0) && (mVsyncTimeStamp != 0) ) {
+ // Compute presentation time stamp in future as per the following formula
+ // future time stamp = vfe time stamp + N * average vsync interval
+ // Adjust the time stamp so that it is placed few milliseconds before
+ // the expected vsync.
+ // Adjust the time stamp for the period where vsync time stamp and VFE
+ // timstamp cross over due difference in fps.
+ presentationTimeStamp = frameTimeStamp +
+ (mNum_vsync_from_vfe_isr_to_presentation_timestamp * mAvgVsyncInterval);
+ if (presentationTimeStamp > mVsyncTimeStamp) {
+ timeDifference = presentationTimeStamp - mVsyncTimeStamp;
+ moveToNextVsync = mAvgVsyncInterval - mVfe_and_mdp_freq_wiggle_filter_min_ms;
+ keepInCurrentVsync = mAvgVsyncInterval - mVfe_and_mdp_freq_wiggle_filter_max_ms;
+ vsyncOffset = timeDifference % mAvgVsyncInterval;
+ expectedVsyncOffset = mAvgVsyncInterval -
+ mSet_timestamp_num_ms_prior_to_vsync - vsyncOffset;
+ if (vsyncOffset > moveToNextVsync) {
+ mAdditionalVsyncOffsetForWiggle = mAvgVsyncInterval;
+ } else if (vsyncOffset < keepInCurrentVsync) {
+ mAdditionalVsyncOffsetForWiggle = 0;
+ }
+ LOGD("vsyncTimeStamp: %llu presentationTimeStamp: %llu expectedVsyncOffset: %d \
+ timeDifference: %llu vsyncffset: %d avgvsync: %llu \
+ additionalvsyncOffsetForWiggle: %llu",
+ mVsyncTimeStamp, presentationTimeStamp, expectedVsyncOffset,
+ timeDifference, vsyncOffset, mAvgVsyncInterval,
+ mAdditionalVsyncOffsetForWiggle);
+ }
+ presentationTimeStamp = presentationTimeStamp + expectedVsyncOffset +
+ mAdditionalVsyncOffsetForWiggle;
+ }
+ return presentationTimeStamp;
+}
+
+}; // namespace qcamera
diff --git a/camera/QCamera2/util/QCameraDisplay.h b/camera/QCamera2/util/QCameraDisplay.h
new file mode 100644
index 0000000..8b7e4c9
--- /dev/null
+++ b/camera/QCamera2/util/QCameraDisplay.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2015-2016, 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.
+ *
+ */
+
+#ifndef __QCAMERADISPLAY_H__
+#define __QCAMERADISPLAY_H__
+
+#include <gui/DisplayEventReceiver.h>
+#include <android/looper.h>
+#include <utils/Looper.h>
+
+namespace qcamera {
+
+#define CAMERA_NUM_VSYNC_INTERVAL_HISTORY 6
+
+class QCameraDisplay {
+public:
+ QCameraDisplay();
+ ~QCameraDisplay();
+ static int vsyncEventReceiverCamera(int fd, int events, void* data);
+ static void* vsyncThreadCamera(void * data);
+ void computeAverageVsyncInterval(nsecs_t currentVsyncTimeStamp);
+ nsecs_t computePresentationTimeStamp(nsecs_t frameTimeStamp);
+
+private:
+ pthread_t mVsyncThreadCameraHandle;
+ nsecs_t mVsyncTimeStamp;
+ nsecs_t mAvgVsyncInterval;
+ nsecs_t mOldTimeStamp;
+ nsecs_t mVsyncIntervalHistory[CAMERA_NUM_VSYNC_INTERVAL_HISTORY];
+ nsecs_t mVsyncHistoryIndex;
+ nsecs_t mAdditionalVsyncOffsetForWiggle;
+ uint32_t mThreadExit;
+ // Tunable property. Increasing this will increase the frame delay and will loose
+ // the real time display.
+ uint32_t mNum_vsync_from_vfe_isr_to_presentation_timestamp;
+ // Tunable property. Set the time stamp x ms prior to expected vsync so that
+ // it will be picked in that vsync
+ uint32_t mSet_timestamp_num_ms_prior_to_vsync;
+ // Tunable property for filtering timestamp wiggle when VFE ISR crosses
+ // over MDP ISR over a period. Typical scenario is VFE is running at
+ // 30.2 fps vs display running at 60 fps.
+ uint32_t mVfe_and_mdp_freq_wiggle_filter_max_ms;
+ uint32_t mVfe_and_mdp_freq_wiggle_filter_min_ms;
+
+ android::DisplayEventReceiver mDisplayEventReceiver;
+};
+
+}; // namespace qcamera
+
+#endif /* __QCAMERADISPLAY_H__ */
diff --git a/camera/QCamera2/util/QCameraFlash.cpp b/camera/QCamera2/util/QCameraFlash.cpp
new file mode 100644
index 0000000..db517b6
--- /dev/null
+++ b/camera/QCamera2/util/QCameraFlash.cpp
@@ -0,0 +1,413 @@
+/* Copyright (c) 2015-2016, 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.
+*
+*/
+
+// System dependencies
+#include <stdio.h>
+#include <fcntl.h>
+#include <media/msm_cam_sensor.h>
+
+// Camera dependencies
+#include "HAL3/QCamera3HWI.h"
+#include "QCameraFlash.h"
+
+extern "C" {
+#include "mm_camera_dbg.h"
+}
+
+#define STRING_LENGTH_OF_64_BIT_NUMBER 21
+
+volatile uint32_t gCamHal3LogLevel = 1;
+
+namespace qcamera {
+
+/*===========================================================================
+ * FUNCTION : getInstance
+ *
+ * DESCRIPTION: Get and create the QCameraFlash singleton.
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraFlash& QCameraFlash::getInstance()
+{
+ static QCameraFlash flashInstance;
+ return flashInstance;
+}
+
+/*===========================================================================
+ * FUNCTION : QCameraFlash
+ *
+ * DESCRIPTION: default constructor of QCameraFlash
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraFlash::QCameraFlash() : m_callbacks(NULL)
+{
+ memset(&m_flashOn, 0, sizeof(m_flashOn));
+ memset(&m_cameraOpen, 0, sizeof(m_cameraOpen));
+ for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) {
+ m_flashFds[pos] = -1;
+ }
+}
+
+/*===========================================================================
+ * FUNCTION : ~QCameraFlash
+ *
+ * DESCRIPTION: deconstructor of QCameraFlash
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraFlash::~QCameraFlash()
+{
+ for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) {
+ if (m_flashFds[pos] >= 0)
+ {
+ setFlashMode(pos, false);
+ close(m_flashFds[pos]);
+ m_flashFds[pos] = -1;
+ }
+ }
+}
+
+/*===========================================================================
+ * FUNCTION : registerCallbacks
+ *
+ * DESCRIPTION: provide flash module with reference to callbacks to framework
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+int32_t QCameraFlash::registerCallbacks(
+ const camera_module_callbacks_t* callbacks)
+{
+ int32_t retVal = 0;
+ m_callbacks = callbacks;
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : initFlash
+ *
+ * DESCRIPTION: Reserve and initialize the flash unit associated with a
+ * given camera id. This function is blocking until the
+ * operation completes or fails. Each flash unit can be "inited"
+ * by only one process at a time.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash.
+ *
+ * RETURN :
+ * 0 : success
+ * -EBUSY : The flash unit or the resource needed to turn on the
+ * the flash is busy, typically because the flash is
+ * already in use.
+ * -EINVAL : No flash present at camera_id.
+ *==========================================================================*/
+int32_t QCameraFlash::initFlash(const int camera_id)
+{
+ int32_t retVal = 0;
+ bool hasFlash = false;
+ char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
+ char flashPath[QCAMERA_MAX_FILEPATH_LENGTH] = "/dev/";
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ return -EINVAL;
+ }
+
+ QCamera3HardwareInterface::getFlashInfo(camera_id,
+ hasFlash,
+ flashNode);
+
+ strlcat(flashPath,
+ flashNode,
+ sizeof(flashPath));
+
+ if (!hasFlash) {
+ LOGE("No flash available for camera id: %d",
+ camera_id);
+ retVal = -EINVAL;
+ } else if (m_cameraOpen[camera_id]) {
+ LOGE("Camera in use for camera id: %d",
+ camera_id);
+ retVal = -EBUSY;
+ } else if (m_flashFds[camera_id] >= 0) {
+ LOGD("Flash is already inited for camera id: %d",
+ camera_id);
+ } else {
+ m_flashFds[camera_id] = open(flashPath, O_RDWR | O_NONBLOCK);
+
+ if (m_flashFds[camera_id] < 0) {
+ LOGE("Unable to open node '%s'",
+ flashPath);
+ retVal = -EBUSY;
+ } else {
+ struct msm_flash_cfg_data_t cfg;
+ struct msm_flash_init_info_t init_info;
+ memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t));
+ memset(&init_info, 0, sizeof(struct msm_flash_init_info_t));
+ init_info.flash_driver_type = FLASH_DRIVER_DEFAULT;
+ cfg.cfg.flash_init_info = &init_info;
+ cfg.cfg_type = CFG_FLASH_INIT;
+ retVal = ioctl(m_flashFds[camera_id],
+ VIDIOC_MSM_FLASH_CFG,
+ &cfg);
+ if (retVal < 0) {
+ LOGE("Unable to init flash for camera id: %d",
+ camera_id);
+ close(m_flashFds[camera_id]);
+ m_flashFds[camera_id] = -1;
+ }
+
+ /* wait for PMIC to init */
+ usleep(5000);
+ }
+ }
+
+ LOGD("X, retVal = %d", retVal);
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : setFlashMode
+ *
+ * DESCRIPTION: Turn on or off the flash associated with a given handle.
+ * This function is blocking until the operation completes or
+ * fails.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash
+ * @on : Whether to turn flash on (true) or off (false)
+ *
+ * RETURN :
+ * 0 : success
+ * -EINVAL : No camera present at camera_id, or it is not inited.
+ * -EALREADY: Flash is already in requested state
+ *==========================================================================*/
+int32_t QCameraFlash::setFlashMode(const int camera_id, const bool mode)
+{
+ int32_t retVal = 0;
+ struct msm_flash_cfg_data_t cfg;
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ retVal = -EINVAL;
+ } else if (mode == m_flashOn[camera_id]) {
+ LOGD("flash %d is already in requested state: %d",
+ camera_id,
+ mode);
+ retVal = -EALREADY;
+ } else if (m_flashFds[camera_id] < 0) {
+ LOGE("called for uninited flash: %d", camera_id);
+ retVal = -EINVAL;
+ } else {
+ memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t));
+ for (int i = 0; i < MAX_LED_TRIGGERS; i++)
+ cfg.flash_current[i] = QCAMERA_TORCH_CURRENT_VALUE;
+ cfg.cfg_type = mode ? CFG_FLASH_LOW: CFG_FLASH_OFF;
+
+ retVal = ioctl(m_flashFds[camera_id],
+ VIDIOC_MSM_FLASH_CFG,
+ &cfg);
+ if (retVal < 0) {
+ LOGE("Unable to change flash mode to %d for camera id: %d",
+ mode, camera_id);
+ } else
+ {
+ m_flashOn[camera_id] = mode;
+ }
+ }
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : deinitFlash
+ *
+ * DESCRIPTION: Release the flash unit associated with a given camera
+ * position. This function is blocking until the operation
+ * completes or fails.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash.
+ *
+ * RETURN :
+ * 0 : success
+ * -EINVAL : No camera present at camera_id or not inited.
+ *==========================================================================*/
+int32_t QCameraFlash::deinitFlash(const int camera_id)
+{
+ int32_t retVal = 0;
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ retVal = -EINVAL;
+ } else if (m_flashFds[camera_id] < 0) {
+ LOGE("called deinitFlash for uninited flash");
+ retVal = -EINVAL;
+ } else {
+ setFlashMode(camera_id, false);
+
+ struct msm_flash_cfg_data_t cfg;
+ cfg.cfg_type = CFG_FLASH_RELEASE;
+ retVal = ioctl(m_flashFds[camera_id],
+ VIDIOC_MSM_FLASH_CFG,
+ &cfg);
+ if (retVal < 0) {
+ LOGE("Failed to release flash for camera id: %d",
+ camera_id);
+ }
+
+ close(m_flashFds[camera_id]);
+ m_flashFds[camera_id] = -1;
+ }
+
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : reserveFlashForCamera
+ *
+ * DESCRIPTION: Give control of the flash to the camera, and notify
+ * framework that the flash has become unavailable.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash.
+ *
+ * RETURN :
+ * 0 : success
+ * -EINVAL : No camera present at camera_id or not inited.
+ * -ENOSYS : No callback available for torch_mode_status_change.
+ *==========================================================================*/
+int32_t QCameraFlash::reserveFlashForCamera(const int camera_id)
+{
+ int32_t retVal = 0;
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ retVal = -EINVAL;
+ } else if (m_cameraOpen[camera_id]) {
+ LOGD("Flash already reserved for camera id: %d",
+ camera_id);
+ } else {
+ if (m_flashOn[camera_id]) {
+ setFlashMode(camera_id, false);
+ deinitFlash(camera_id);
+ }
+ m_cameraOpen[camera_id] = true;
+
+ bool hasFlash = false;
+ char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
+
+ QCamera3HardwareInterface::getFlashInfo(camera_id,
+ hasFlash,
+ flashNode);
+
+ if (m_callbacks == NULL ||
+ m_callbacks->torch_mode_status_change == NULL) {
+ LOGE("Callback is not defined!");
+ retVal = -ENOSYS;
+ } else if (!hasFlash) {
+ LOGD("Suppressing callback "
+ "because no flash exists for camera id: %d",
+ camera_id);
+ } else {
+ char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
+ snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
+ "%d", camera_id);
+ m_callbacks->torch_mode_status_change(m_callbacks,
+ cameraIdStr,
+ TORCH_MODE_STATUS_NOT_AVAILABLE);
+ }
+ }
+
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : releaseFlashFromCamera
+ *
+ * DESCRIPTION: Release control of the flash from the camera, and notify
+ * framework that the flash has become available.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash.
+ *
+ * RETURN :
+ * 0 : success
+ * -EINVAL : No camera present at camera_id or not inited.
+ * -ENOSYS : No callback available for torch_mode_status_change.
+ *==========================================================================*/
+int32_t QCameraFlash::releaseFlashFromCamera(const int camera_id)
+{
+ int32_t retVal = 0;
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ retVal = -EINVAL;
+ } else if (!m_cameraOpen[camera_id]) {
+ LOGD("Flash not reserved for camera id: %d",
+ camera_id);
+ } else {
+ m_cameraOpen[camera_id] = false;
+
+ bool hasFlash = false;
+ char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
+
+ QCamera3HardwareInterface::getFlashInfo(camera_id,
+ hasFlash,
+ flashNode);
+
+ if (m_callbacks == NULL ||
+ m_callbacks->torch_mode_status_change == NULL) {
+ LOGE("Callback is not defined!");
+ retVal = -ENOSYS;
+ } else if (!hasFlash) {
+ LOGD("Suppressing callback "
+ "because no flash exists for camera id: %d",
+ camera_id);
+ } else {
+ char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
+ snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
+ "%d", camera_id);
+ m_callbacks->torch_mode_status_change(m_callbacks,
+ cameraIdStr,
+ TORCH_MODE_STATUS_AVAILABLE_OFF);
+ }
+ }
+
+ return retVal;
+}
+
+}; // namespace qcamera
diff --git a/camera/QCamera2/util/QCameraFlash.h b/camera/QCamera2/util/QCameraFlash.h
new file mode 100644
index 0000000..fa5e3ea
--- /dev/null
+++ b/camera/QCamera2/util/QCameraFlash.h
@@ -0,0 +1,69 @@
+/* Copyright (c) 2015-2016, 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.
+ *
+ */
+
+#ifndef __QCAMERA_FLASH_H__
+#define __QCAMERA_FLASH_H__
+
+// Camera dependencies
+#include "camera_common.h"
+
+extern "C" {
+#include "mm_camera_interface.h"
+}
+
+namespace qcamera {
+
+#define QCAMERA_TORCH_CURRENT_VALUE 200
+
+class QCameraFlash {
+public:
+ static QCameraFlash& getInstance();
+
+ int32_t registerCallbacks(const camera_module_callbacks_t* callbacks);
+ int32_t initFlash(const int camera_id);
+ int32_t setFlashMode(const int camera_id, const bool on);
+ int32_t deinitFlash(const int camera_id);
+ int32_t reserveFlashForCamera(const int camera_id);
+ int32_t releaseFlashFromCamera(const int camera_id);
+
+private:
+ QCameraFlash();
+ virtual ~QCameraFlash();
+ QCameraFlash(const QCameraFlash&);
+ QCameraFlash& operator=(const QCameraFlash&);
+
+ const camera_module_callbacks_t *m_callbacks;
+ int32_t m_flashFds[MM_CAMERA_MAX_NUM_SENSORS];
+ bool m_flashOn[MM_CAMERA_MAX_NUM_SENSORS];
+ bool m_cameraOpen[MM_CAMERA_MAX_NUM_SENSORS];
+};
+
+}; // namespace qcamera
+
+#endif /* __QCAMERA_FLASH_H__ */
diff --git a/camera/QCamera2/util/QCameraPerf.cpp b/camera/QCamera2/util/QCameraPerf.cpp
new file mode 100644
index 0000000..83ba4cc
--- /dev/null
+++ b/camera/QCamera2/util/QCameraPerf.cpp
@@ -0,0 +1,545 @@
+/* Copyright (c) 2015-2016, 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"
+
+// To remove
+#include <cutils/properties.h>
+
+// System dependencies
+#include <stdlib.h>
+#include <dlfcn.h>
+
+// Camera dependencies
+#include "QCameraPerf.h"
+#include "QCameraTrace.h"
+
+extern "C" {
+#include "mm_camera_dbg.h"
+}
+
+namespace qcamera {
+
+/*===========================================================================
+ * 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),
+ mPerfLockHandleTimed(-1),
+ mTimerSet(0),
+ mPerfLockTimeout(0),
+ mStartTimeofLock(0)
+{
+}
+
+/*===========================================================================
+ * 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];
+
+ LOGD("E");
+ Mutex::Autolock lock(mLock);
+
+ // Clear the list of active power hints
+ mActivePowerHints.clear();
+ mCurrentPowerHint = static_cast<power_hint_t>(0);
+ mCurrentPowerHintEnable = false;
+
+ property_get("persist.camera.perflock.enable", value, "1");
+ mPerfLockEnable = atoi(value);
+#ifdef HAS_MULTIMEDIA_HINTS
+ if (hw_get_module(POWER_HARDWARE_MODULE_ID, (const hw_module_t **)&m_pPowerModule)) {
+ LOGE("%s module not found", POWER_HARDWARE_MODULE_ID);
+ }
+#endif
+
+ 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) {
+ LOGE("failed to perf_lock_acq function handle");
+ goto cleanup;
+ }
+
+ perf_lock_rel = (int (*) (int))dlsym(mDlHandle, "perf_lock_rel");
+ if ((rc = dlerror()) != NULL) {
+ LOGE("failed to perf_lock_rel function handle");
+ goto cleanup;
+ }
+ LOGD("X");
+ return;
+
+cleanup:
+ perf_lock_acq = NULL;
+ perf_lock_rel = NULL;
+ mPerfLockEnable = 0;
+ if (mDlHandle) {
+ dlclose(mDlHandle);
+ mDlHandle = NULL;
+ }
+ }
+ LOGD("X");
+}
+
+/*===========================================================================
+ * FUNCTION : lock_deinit
+ *
+ * DESCRIPTION: deinitialize the perf lock parameters
+ *
+ * PARAMETERS :
+ * None
+ *
+ * RETURN : void
+ *
+ *==========================================================================*/
+void QCameraPerfLock::lock_deinit()
+{
+ Mutex::Autolock lock(mLock);
+ if (mPerfLockEnable) {
+ LOGD("E");
+
+ if (mActivePowerHints.empty() == false) {
+ // Disable the active power hint
+ mCurrentPowerHint = *mActivePowerHints.begin();
+ powerHintInternal(mCurrentPowerHint, false);
+ mActivePowerHints.clear();
+ }
+
+ if ((NULL != perf_lock_rel) && (mPerfLockHandleTimed >= 0)) {
+ (*perf_lock_rel)(mPerfLockHandleTimed);
+ }
+
+ if ((NULL != perf_lock_rel) && (mPerfLockHandle >= 0)) {
+ (*perf_lock_rel)(mPerfLockHandle);
+ }
+
+ if (mDlHandle) {
+ perf_lock_acq = NULL;
+ perf_lock_rel = NULL;
+
+ dlclose(mDlHandle);
+ mDlHandle = NULL;
+ }
+ mPerfLockEnable = 0;
+ LOGD("X");
+ }
+}
+
+/*===========================================================================
+ * FUNCTION : isTimerReset
+ *
+ * DESCRIPTION: Check if timout duration is reached
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : true if timeout reached
+ * false if timeout not reached
+ *
+ *==========================================================================*/
+bool QCameraPerfLock::isTimerReset()
+{
+ Mutex::Autolock lock(mLock);
+ if (mPerfLockEnable && mTimerSet) {
+ nsecs_t timeDiff = systemTime() - mStartTimeofLock;
+ if (ns2ms(timeDiff) > (uint32_t)mPerfLockTimeout) {
+ resetTimer();
+ return true;
+ }
+ }
+ return false;
+}
+
+/*===========================================================================
+ * FUNCTION : resetTimer
+ *
+ * DESCRIPTION: Reset the timer used in timed perf lock
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : void
+ *
+ *==========================================================================*/
+void QCameraPerfLock::resetTimer()
+{
+ mPerfLockTimeout = 0;
+ mTimerSet = 0;
+}
+
+/*===========================================================================
+ * FUNCTION : start_timer
+ *
+ * DESCRIPTION: get the start of the timer
+ *
+ * PARAMETERS :
+ * @timer_val: timer duration in milliseconds
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *
+ *==========================================================================*/
+void QCameraPerfLock::startTimer(uint32_t timer_val)
+{
+ mStartTimeofLock = systemTime();
+ mTimerSet = 1;
+ mPerfLockTimeout = timer_val;
+}
+
+/*===========================================================================
+ * FUNCTION : lock_acq_timed
+ *
+ * DESCRIPTION: Acquire the performance lock for the specified duration.
+ * If an existing lock timeout has not elapsed, extend the
+ * lock further for the specified duration
+ *
+ * PARAMETERS :
+ * @timer_val: lock duration
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *
+ *==========================================================================*/
+int32_t QCameraPerfLock::lock_acq_timed(int32_t timer_val)
+{
+ int32_t ret = -1;
+
+ LOGD("E");
+ 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 (mTimerSet) {
+ nsecs_t curElapsedTime = systemTime() - mStartTimeofLock;
+ int32_t pendingTimeout = mPerfLockTimeout - ns2ms(curElapsedTime);
+ timer_val += pendingTimeout;
+ }
+ startTimer(timer_val);
+
+ // Disable power hint when acquiring the perf lock
+ if (mCurrentPowerHintEnable) {
+ LOGD("mCurrentPowerHintEnable %d" ,mCurrentPowerHintEnable);
+ powerHintInternal(mCurrentPowerHint, false);
+ }
+
+ if ((NULL != perf_lock_acq) && (mPerfLockHandleTimed < 0)) {
+ ret = (*perf_lock_acq)(mPerfLockHandleTimed, timer_val, perf_lock_params,
+ sizeof(perf_lock_params) / sizeof(int32_t));
+ LOGD("ret %d", ret);
+ if (ret < 0) {
+ LOGE("failed to acquire lock");
+ } else {
+ mPerfLockHandleTimed = ret;
+ }
+ }
+ LOGD("perf_handle_acq %d ", mPerfLockHandleTimed);
+ }
+
+ LOGD("X");
+ return ret;
+}
+
+/*===========================================================================
+ * 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;
+
+ LOGD("E");
+ 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
+ };
+
+ // Disable power hint when acquiring the perf lock
+ if (mCurrentPowerHintEnable) {
+ powerHintInternal(mCurrentPowerHint, false);
+ }
+
+ if ((NULL != perf_lock_acq) && (mPerfLockHandle < 0)) {
+ ret = (*perf_lock_acq)(mPerfLockHandle, ONE_SEC, perf_lock_params,
+ sizeof(perf_lock_params) / sizeof(int32_t));
+ LOGD("ret %d", ret);
+ if (ret < 0) {
+ LOGE("failed to acquire lock");
+ } else {
+ mPerfLockHandle = ret;
+ }
+ }
+ LOGD("perf_handle_acq %d ", mPerfLockHandle);
+ }
+
+ LOGD("X");
+ return ret;
+}
+
+/*===========================================================================
+ * FUNCTION : lock_rel_timed
+ *
+ * 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_timed()
+{
+ int ret = -1;
+ Mutex::Autolock lock(mLock);
+ if (mPerfLockEnable) {
+ LOGD("E");
+ if (mPerfLockHandleTimed < 0) {
+ LOGW("mPerfLockHandle < 0,check if lock is acquired");
+ return ret;
+ }
+ LOGD("perf_handle_rel %d ", mPerfLockHandleTimed);
+
+ if ((NULL != perf_lock_rel) && (0 <= mPerfLockHandleTimed)) {
+ ret = (*perf_lock_rel)(mPerfLockHandleTimed);
+ if (ret < 0) {
+ LOGE("failed to release lock");
+ }
+ mPerfLockHandleTimed = -1;
+ resetTimer();
+ }
+
+ if ((mCurrentPowerHintEnable == 1) && (mTimerSet == 0)) {
+ powerHintInternal(mCurrentPowerHint, mCurrentPowerHintEnable);
+ }
+ LOGD("X");
+ }
+ 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) {
+ LOGD("E");
+ if (mPerfLockHandle < 0) {
+ LOGW("mPerfLockHandle < 0,check if lock is acquired");
+ return ret;
+ }
+ LOGD("perf_handle_rel %d ", mPerfLockHandle);
+
+ if ((NULL != perf_lock_rel) && (0 <= mPerfLockHandle)) {
+ ret = (*perf_lock_rel)(mPerfLockHandle);
+ if (ret < 0) {
+ LOGE("failed to release lock");
+ }
+ mPerfLockHandle = -1;
+ }
+
+ if (mCurrentPowerHintEnable == 1) {
+ powerHintInternal(mCurrentPowerHint, mCurrentPowerHintEnable);
+ }
+ LOGD("X");
+ }
+ return ret;
+}
+
+/*===========================================================================
+ * FUNCTION : powerHintInternal
+ *
+ * DESCRIPTION: Sets the requested power hint and state to power HAL.
+ *
+ * PARAMETERS :
+ * hint : Power hint
+ * enable : Enable power hint if set to 1. Disable if set to 0.
+ * RETURN : void
+ *
+ *==========================================================================*/
+void QCameraPerfLock::powerHintInternal(power_hint_t hint, bool enable)
+{
+#ifdef HAS_MULTIMEDIA_HINTS
+ if (m_pPowerModule != NULL) {
+ if (enable == true) {
+ m_pPowerModule->powerHint(m_pPowerModule, hint, (void *)"state=1");
+ } else {
+ m_pPowerModule->powerHint(m_pPowerModule, hint, (void *)"state=0");
+ }
+ }
+#endif
+}
+
+/*===========================================================================
+ * FUNCTION : powerHint
+ *
+ * DESCRIPTION: Updates the list containing active/enabled power hints.
+ * If needed, calls the internal powerHint function with
+ * requested power hint and state.
+ * PARAMETERS :
+ * hint : Power hint
+ * enable : Enable power hint if set to 1. Disable if set to 0.
+ * RETURN : void
+ *
+ *==========================================================================*/
+void QCameraPerfLock::powerHint(power_hint_t hint, bool enable)
+{
+#ifdef HAS_MULTIMEDIA_HINTS
+ if (enable == true) {
+ if ((hint != mCurrentPowerHint) || (enable != mCurrentPowerHintEnable)) {
+ // Disable the current active power hint
+ if (mCurrentPowerHintEnable == true) {
+ powerHintInternal(mCurrentPowerHint, false);
+ }
+ // Push the new power hint at the head of the active power hint list
+ mActivePowerHints.push_front(hint);
+
+ // Set the new power hint
+ mCurrentPowerHint = hint;
+ mCurrentPowerHintEnable = enable;
+ powerHintInternal(hint, enable);
+ }
+ } else {
+ // Remove the power hint from the list
+ for (List<power_hint_t>::iterator it = mActivePowerHints.begin();
+ it != mActivePowerHints.end(); ++it) {
+ if (*it == hint) {
+ if (it != mActivePowerHints.begin()) {
+ LOGW("Request to remove the previous power hint: %d instead of "
+ "currently active power hint: %d", static_cast<int>(hint),
+ static_cast<int>(mCurrentPowerHint));
+ }
+ mActivePowerHints.erase(it);
+ break;
+ }
+ }
+
+ if (hint == mCurrentPowerHint) {
+ // Disable the power hint
+ powerHintInternal(hint, false);
+
+ // If the active power hint list is not empty,
+ // restore the previous power hint from the head of the list
+ if (mActivePowerHints.empty() == false) {
+ mCurrentPowerHint = *mActivePowerHints.begin();
+ mCurrentPowerHintEnable = true;
+ powerHintInternal(mCurrentPowerHint, true);
+ } else {
+ mCurrentPowerHint = static_cast<power_hint_t>(0);
+ mCurrentPowerHintEnable = false;
+ }
+ }
+ }
+#endif
+}
+
+}; // namespace qcamera
diff --git a/camera/QCamera2/util/QCameraPerf.h b/camera/QCamera2/util/QCameraPerf.h
new file mode 100644
index 0000000..0096139
--- /dev/null
+++ b/camera/QCamera2/util/QCameraPerf.h
@@ -0,0 +1,93 @@
+/* Copyright (c) 2015-2016, 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.
+ *
+ */
+
+#ifndef __QCAMERAPERF_H__
+#define __QCAMERAPERF_H__
+
+// System dependencies
+#include <utils/List.h>
+#include <utils/Mutex.h>
+
+// Camera dependencies
+#include "power.h"
+
+typedef enum {
+ ALL_CORES_ONLINE = 0x7FE,
+ ALL_CPUS_PWR_CLPS_DIS = 0x101,
+ CPU0_MIN_FREQ_TURBO_MAX = 0x2FE,
+ CPU4_MIN_FREQ_TURBO_MAX = 0x1FFE,
+}perf_lock_params_t;
+
+/* Time related macros */
+#define ONE_SEC 1000
+typedef int64_t nsecs_t;
+#define NSEC_PER_SEC 1000000000LLU
+
+using namespace android;
+
+namespace qcamera {
+
+class QCameraPerfLock {
+public:
+ QCameraPerfLock();
+ ~QCameraPerfLock();
+
+ void lock_init();
+ void lock_deinit();
+ int32_t lock_rel();
+ int32_t lock_acq();
+ int32_t lock_acq_timed(int32_t timer_val);
+ int32_t lock_rel_timed();
+ bool isTimerReset();
+ void powerHintInternal(power_hint_t hint, bool enable);
+ void powerHint(power_hint_t hint, bool enable);
+ bool isPerfLockTimedAcquired() { return (0 <= mPerfLockHandleTimed); }
+
+private:
+ int32_t (*perf_lock_acq)(int, int, int[], int);
+ int32_t (*perf_lock_rel)(int);
+ void startTimer(uint32_t timer_val);
+ void resetTimer();
+ void *mDlHandle;
+ uint32_t mPerfLockEnable;
+ Mutex mLock;
+ int32_t mPerfLockHandle; // Performance lock library handle
+ int32_t mPerfLockHandleTimed; // Performance lock library handle
+ power_module_t *m_pPowerModule; // power module Handle
+ power_hint_t mCurrentPowerHint;
+ bool mCurrentPowerHintEnable;
+ uint32_t mTimerSet;
+ uint32_t mPerfLockTimeout;
+ nsecs_t mStartTimeofLock;
+ List<power_hint_t> mActivePowerHints; // Active/enabled power hints list
+};
+
+}; // namespace qcamera
+
+#endif /* __QCAMREAPERF_H__ */
diff --git a/camera/QCamera2/util/QCameraQueue.cpp b/camera/QCamera2/util/QCameraQueue.cpp
new file mode 100644
index 0000000..3b9d239
--- /dev/null
+++ b/camera/QCamera2/util/QCameraQueue.cpp
@@ -0,0 +1,464 @@
+/* Copyright (c) 2012-2016, 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.
+*
+*/
+
+// System dependencies
+#include <string.h>
+#include <utils/Errors.h>
+
+// Camera dependencies
+#include "QCameraQueue.h"
+
+extern "C" {
+#include "mm_camera_dbg.h"
+}
+
+namespace qcamera {
+
+/*===========================================================================
+ * FUNCTION : QCameraQueue
+ *
+ * DESCRIPTION: default constructor of QCameraQueue
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraQueue::QCameraQueue()
+{
+ pthread_mutex_init(&m_lock, NULL);
+ cam_list_init(&m_head.list);
+ m_size = 0;
+ m_dataFn = NULL;
+ m_userData = NULL;
+ m_active = true;
+}
+
+/*===========================================================================
+ * FUNCTION : QCameraQueue
+ *
+ * DESCRIPTION: constructor of QCameraQueue
+ *
+ * PARAMETERS :
+ * @data_rel_fn : function ptr to release node data internal resource
+ * @user_data : user data ptr
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraQueue::QCameraQueue(release_data_fn data_rel_fn, void *user_data)
+{
+ pthread_mutex_init(&m_lock, NULL);
+ cam_list_init(&m_head.list);
+ m_size = 0;
+ m_dataFn = data_rel_fn;
+ m_userData = user_data;
+ m_active = true;
+}
+
+/*===========================================================================
+ * FUNCTION : ~QCameraQueue
+ *
+ * DESCRIPTION: deconstructor of QCameraQueue
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraQueue::~QCameraQueue()
+{
+ flush();
+ pthread_mutex_destroy(&m_lock);
+}
+
+/*===========================================================================
+ * FUNCTION : init
+ *
+ * DESCRIPTION: Put the queue to active state (ready to enqueue and dequeue)
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+void QCameraQueue::init()
+{
+ pthread_mutex_lock(&m_lock);
+ m_active = true;
+ pthread_mutex_unlock(&m_lock);
+}
+
+/*===========================================================================
+ * FUNCTION : isEmpty
+ *
+ * DESCRIPTION: return if the queue is empty or not
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : true -- queue is empty; false -- not empty
+ *==========================================================================*/
+bool QCameraQueue::isEmpty()
+{
+ bool flag = true;
+ pthread_mutex_lock(&m_lock);
+ if (m_size > 0) {
+ flag = false;
+ }
+ pthread_mutex_unlock(&m_lock);
+ return flag;
+}
+
+/*===========================================================================
+ * FUNCTION : enqueue
+ *
+ * DESCRIPTION: enqueue data into the queue
+ *
+ * PARAMETERS :
+ * @data : data to be enqueued
+ *
+ * RETURN : true -- success; false -- failed
+ *==========================================================================*/
+bool QCameraQueue::enqueue(void *data)
+{
+ bool rc;
+ camera_q_node *node =
+ (camera_q_node *)malloc(sizeof(camera_q_node));
+ if (NULL == node) {
+ LOGE("No memory for camera_q_node");
+ return false;
+ }
+
+ memset(node, 0, sizeof(camera_q_node));
+ node->data = data;
+
+ pthread_mutex_lock(&m_lock);
+ if (m_active) {
+ cam_list_add_tail_node(&node->list, &m_head.list);
+ m_size++;
+ rc = true;
+ } else {
+ free(node);
+ rc = false;
+ }
+ pthread_mutex_unlock(&m_lock);
+ return rc;
+}
+
+/*===========================================================================
+ * FUNCTION : enqueueWithPriority
+ *
+ * DESCRIPTION: enqueue data into queue with priority, will insert into the
+ * head of the queue
+ *
+ * PARAMETERS :
+ * @data : data to be enqueued
+ *
+ * RETURN : true -- success; false -- failed
+ *==========================================================================*/
+bool QCameraQueue::enqueueWithPriority(void *data)
+{
+ bool rc;
+ camera_q_node *node =
+ (camera_q_node *)malloc(sizeof(camera_q_node));
+ if (NULL == node) {
+ LOGE("No memory for camera_q_node");
+ return false;
+ }
+
+ memset(node, 0, sizeof(camera_q_node));
+ node->data = data;
+
+ pthread_mutex_lock(&m_lock);
+ if (m_active) {
+ struct cam_list *p_next = m_head.list.next;
+
+ m_head.list.next = &node->list;
+ p_next->prev = &node->list;
+ node->list.next = p_next;
+ node->list.prev = &m_head.list;
+
+ m_size++;
+ rc = true;
+ } else {
+ free(node);
+ rc = false;
+ }
+ pthread_mutex_unlock(&m_lock);
+ return rc;
+}
+
+/*===========================================================================
+ * FUNCTION : peek
+ *
+ * DESCRIPTION: return the head element without removing it
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : data ptr. NULL if not any data in the queue.
+ *==========================================================================*/
+void* QCameraQueue::peek()
+{
+ camera_q_node* node = NULL;
+ void* data = NULL;
+ struct cam_list *head = NULL;
+ struct cam_list *pos = NULL;
+
+ pthread_mutex_lock(&m_lock);
+ if (m_active) {
+ head = &m_head.list;
+ pos = head->next;
+ if (pos != head) {
+ node = member_of(pos, camera_q_node, list);
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+
+ if (NULL != node) {
+ data = node->data;
+ }
+
+ return data;
+}
+
+/*===========================================================================
+ * FUNCTION : dequeue
+ *
+ * DESCRIPTION: dequeue data from the queue
+ *
+ * PARAMETERS :
+ * @bFromHead : if true, dequeue from the head
+ * if false, dequeue from the tail
+ *
+ * RETURN : data ptr. NULL if not any data in the queue.
+ *==========================================================================*/
+void* QCameraQueue::dequeue(bool bFromHead)
+{
+ camera_q_node* node = NULL;
+ void* data = NULL;
+ struct cam_list *head = NULL;
+ struct cam_list *pos = NULL;
+
+ pthread_mutex_lock(&m_lock);
+ if (m_active) {
+ head = &m_head.list;
+ if (bFromHead) {
+ pos = head->next;
+ } else {
+ pos = head->prev;
+ }
+ if (pos != head) {
+ node = member_of(pos, camera_q_node, list);
+ cam_list_del_node(&node->list);
+ m_size--;
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+
+ if (NULL != node) {
+ data = node->data;
+ free(node);
+ }
+
+ return data;
+}
+
+/*===========================================================================
+ * FUNCTION : dequeue
+ *
+ * DESCRIPTION: dequeue data from the queue
+ *
+ * PARAMETERS :
+ * @match : matching function callback
+ * @match_data : the actual data to be matched
+ *
+ * RETURN : data ptr. NULL if not any data in the queue.
+ *==========================================================================*/
+void* QCameraQueue::dequeue(match_fn_data match, void *match_data){
+ camera_q_node* node = NULL;
+ struct cam_list *head = NULL;
+ struct cam_list *pos = NULL;
+ void* data = NULL;
+
+ if ( NULL == match || NULL == match_data ) {
+ return NULL;
+ }
+
+ pthread_mutex_lock(&m_lock);
+ if (m_active) {
+ head = &m_head.list;
+ pos = head->next;
+
+ while(pos != head) {
+ node = member_of(pos, camera_q_node, list);
+ pos = pos->next;
+ if (NULL != node) {
+ if ( match(node->data, m_userData, match_data) ) {
+ cam_list_del_node(&node->list);
+ m_size--;
+ data = node->data;
+ free(node);
+ pthread_mutex_unlock(&m_lock);
+ return data;
+ }
+ }
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+ return NULL;
+}
+
+/*===========================================================================
+ * FUNCTION : flush
+ *
+ * DESCRIPTION: flush all nodes from the queue, queue will be empty after this
+ * operation.
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+void QCameraQueue::flush(){
+ camera_q_node* node = NULL;
+ struct cam_list *head = NULL;
+ struct cam_list *pos = NULL;
+
+ pthread_mutex_lock(&m_lock);
+ if (m_active) {
+ head = &m_head.list;
+ pos = head->next;
+
+ while(pos != head) {
+ node = member_of(pos, camera_q_node, list);
+ pos = pos->next;
+ cam_list_del_node(&node->list);
+ m_size--;
+
+ if (NULL != node->data) {
+ if (m_dataFn) {
+ m_dataFn(node->data, m_userData);
+ }
+ free(node->data);
+ }
+ free(node);
+
+ }
+ m_size = 0;
+ m_active = false;
+ }
+ pthread_mutex_unlock(&m_lock);
+}
+
+/*===========================================================================
+ * FUNCTION : flushNodes
+ *
+ * DESCRIPTION: flush only specific nodes, depending on
+ * the given matching function.
+ *
+ * PARAMETERS :
+ * @match : matching function
+ *
+ * RETURN : None
+ *==========================================================================*/
+void QCameraQueue::flushNodes(match_fn match){
+ camera_q_node* node = NULL;
+ struct cam_list *head = NULL;
+ struct cam_list *pos = NULL;
+
+ if ( NULL == match ) {
+ return;
+ }
+
+ pthread_mutex_lock(&m_lock);
+ if (m_active) {
+ head = &m_head.list;
+ pos = head->next;
+
+ while(pos != head) {
+ node = member_of(pos, camera_q_node, list);
+ pos = pos->next;
+ if ( match(node->data, m_userData) ) {
+ cam_list_del_node(&node->list);
+ m_size--;
+
+ if (NULL != node->data) {
+ if (m_dataFn) {
+ m_dataFn(node->data, m_userData);
+ }
+ free(node->data);
+ }
+ free(node);
+ }
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+}
+
+/*===========================================================================
+ * FUNCTION : flushNodes
+ *
+ * DESCRIPTION: flush only specific nodes, depending on
+ * the given matching function.
+ *
+ * PARAMETERS :
+ * @match : matching function
+ *
+ * RETURN : None
+ *==========================================================================*/
+void QCameraQueue::flushNodes(match_fn_data match, void *match_data){
+ camera_q_node* node = NULL;
+ struct cam_list *head = NULL;
+ struct cam_list *pos = NULL;
+
+ if ( NULL == match ) {
+ return;
+ }
+
+ pthread_mutex_lock(&m_lock);
+ if (m_active) {
+ head = &m_head.list;
+ pos = head->next;
+
+ while(pos != head) {
+ node = member_of(pos, camera_q_node, list);
+ pos = pos->next;
+ if ( match(node->data, m_userData, match_data) ) {
+ cam_list_del_node(&node->list);
+ m_size--;
+
+ if (NULL != node->data) {
+ if (m_dataFn) {
+ m_dataFn(node->data, m_userData);
+ }
+ free(node->data);
+ }
+ free(node);
+ }
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+}
+
+}; // namespace qcamera
diff --git a/camera/QCamera2/util/QCameraQueue.h b/camera/QCamera2/util/QCameraQueue.h
new file mode 100644
index 0000000..dfa221e
--- /dev/null
+++ b/camera/QCamera2/util/QCameraQueue.h
@@ -0,0 +1,79 @@
+/* Copyright (c) 2012-2016, 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.
+ *
+ */
+
+#ifndef __QCAMERA_QUEUE_H__
+#define __QCAMERA_QUEUE_H__
+
+// System dependencies
+#include <pthread.h>
+
+// Camera dependencies
+#include "cam_list.h"
+
+namespace qcamera {
+
+typedef bool (*match_fn_data)(void *data, void *user_data, void *match_data);
+typedef void (*release_data_fn)(void* data, void *user_data);
+typedef bool (*match_fn)(void *data, void *user_data);
+
+class QCameraQueue {
+public:
+ QCameraQueue();
+ QCameraQueue(release_data_fn data_rel_fn, void *user_data);
+ virtual ~QCameraQueue();
+ void init();
+ bool enqueue(void *data);
+ bool enqueueWithPriority(void *data);
+ /* This call will put queue into uninitialized state.
+ * Need to call init() in order to use the queue again */
+ void flush();
+ void flushNodes(match_fn match);
+ void flushNodes(match_fn_data match, void *spec_data);
+ void* dequeue(bool bFromHead = true);
+ void* dequeue(match_fn_data match, void *spec_data);
+ void* peek();
+ bool isEmpty();
+ int getCurrentSize() {return m_size;}
+private:
+ typedef struct {
+ struct cam_list list;
+ void* data;
+ } camera_q_node;
+
+ camera_q_node m_head; // dummy head
+ int m_size;
+ bool m_active;
+ pthread_mutex_t m_lock;
+ release_data_fn m_dataFn;
+ void * m_userData;
+};
+
+}; // namespace qcamera
+
+#endif /* __QCAMERA_QUEUE_H__ */
diff --git a/camera/QCamera2/util/QCameraTrace.h b/camera/QCamera2/util/QCameraTrace.h
new file mode 100644
index 0000000..d7eeb8f
--- /dev/null
+++ b/camera/QCamera2/util/QCameraTrace.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __QCAMERATRACE_H__
+#define __QCAMERATRACE_H__
+
+#include <utils/Trace.h>
+
+#ifdef QCAMERA_REDEFINE_LOG
+#define CAM_MODULE CAM_HAL_MODULE
+extern "C" {
+#include "mm_camera_dbg.h"
+}
+#endif
+
+#undef ATRACE_CALL
+#undef ATRACE_NAME
+#undef ATRACE_BEGIN
+#undef ATRACE_INT
+#undef ATRACE_END
+#undef ATRACE_BEGIN_SNPRINTF
+#undef KPI_ATRACE_BEGIN
+#undef KPI_ATRACE_END
+#undef KPI_ATRACE_INT
+#undef ATRACE_TAG
+#undef ATRACE_BEGIN_DBG
+#undef ATRACE_INT_DBG
+#undef ATRACE_END_DBG
+
+#define KPI_ONLY 1
+#define KPI_DBG 2
+
+#define CAMERA_TRACE_BUF 32
+
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+
+//to enable only KPI logs
+#define KPI_ATRACE_BEGIN(name) ({\
+if (gKpiDebugLevel >= KPI_ONLY) { \
+ atrace_begin(ATRACE_TAG, name); \
+}\
+})
+
+#define KPI_ATRACE_END() ({\
+if (gKpiDebugLevel >= KPI_ONLY) { \
+ atrace_end(ATRACE_TAG); \
+}\
+})
+
+#define KPI_ATRACE_INT(name,val) ({\
+if (gKpiDebugLevel >= KPI_ONLY) { \
+ atrace_int(ATRACE_TAG, name, val); \
+}\
+})
+
+
+#define ATRACE_BEGIN_SNPRINTF(fmt_str, ...) \
+ if (gKpiDebugLevel >= KPI_DBG) { \
+ char trace_tag[CAMERA_TRACE_BUF]; \
+ snprintf(trace_tag, CAMERA_TRACE_BUF, fmt_str, ##__VA_ARGS__); \
+ ATRACE_BEGIN(trace_tag); \
+}
+
+#define ATRACE_BEGIN_DBG(name) ({\
+if (gKpiDebugLevel >= KPI_DBG) { \
+ atrace_begin(ATRACE_TAG, name); \
+}\
+})
+
+#define ATRACE_END_DBG() ({\
+if (gKpiDebugLevel >= KPI_DBG) { \
+ atrace_end(ATRACE_TAG); \
+}\
+})
+
+#define ATRACE_INT_DBG(name,val) ({\
+if (gKpiDebugLevel >= KPI_DBG) { \
+ atrace_int(ATRACE_TAG, name, val); \
+}\
+})
+
+#define ATRACE_BEGIN ATRACE_BEGIN_DBG
+#define ATRACE_INT ATRACE_INT_DBG
+#define ATRACE_END ATRACE_END_DBG
+
+#define KPI_ATRACE_NAME(name) qcamera::ScopedTraceKpi ___tracer(ATRACE_TAG, name)
+#define ATRACE_NAME(name) qcamera::ScopedTraceDbg ___tracer(ATRACE_TAG, name)
+#define KPI_ATRACE_CALL() KPI_ATRACE_NAME(__FUNCTION__)
+#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
+
+namespace qcamera {
+extern volatile uint32_t gKpiDebugLevel;
+class ScopedTraceKpi {
+public:
+ inline ScopedTraceKpi(uint64_t tag, const char *name)
+ : mTag(tag) {
+ if (gKpiDebugLevel >= KPI_ONLY) {
+ atrace_begin(mTag,name);
+ }
+ }
+
+ inline ~ScopedTraceKpi() {
+ if (gKpiDebugLevel >= KPI_ONLY) {
+ atrace_end(mTag);
+ }
+ }
+
+ private:
+ uint64_t mTag;
+};
+
+class ScopedTraceDbg {
+public:
+ inline ScopedTraceDbg(uint64_t tag, const char *name)
+ : mTag(tag) {
+ if (gKpiDebugLevel >= KPI_DBG) {
+ atrace_begin(mTag,name);
+ }
+ }
+
+ inline ~ScopedTraceDbg() {
+ if (gKpiDebugLevel >= KPI_DBG) {
+ atrace_end(mTag);
+ }
+ }
+
+ private:
+ uint64_t mTag;
+};
+};
+
+extern volatile uint32_t gKpiDebugLevel;
+
+#endif /* __QCAMREATRACE_H__ */