aboutsummaryrefslogtreecommitdiff
path: root/camera/QCamera2/util/QCameraQueue.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--camera/QCamera2/util/QCameraQueue.cpp464
1 files changed, 464 insertions, 0 deletions
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