/*=========================================================================== * 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) { ALOGE("%s: No memory for camera_cmd_t", __func__); 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 : dataProcRoutine * * DESCRIPTION: function to process data in the main stream thread * * PARAMETERS : * @data : user data ptr * * RETURN : none *==========================================================================*/ void *QCamera3Stream::dataProcRoutine(void *data) { int running = 1; int ret; QCamera3Stream *pme = (QCamera3Stream *)data; QCameraCmdThread *cmdThread = &pme->mProcTh; ALOGV("%s: E", __func__); do { do { ret = cam_sem_wait(&cmdThread->cmd_sem); if (ret != 0 && errno != EINVAL) { ALOGE("%s: cam_sem_wait error (%s)", __func__, strerror(errno)); return NULL; } } while (ret != 0); // we got notified about new cmd avail in cmd queue camera_cmd_type_t cmd = cmdThread->getCmd(); switch (cmd) { case CAMERA_CMD_TYPE_DO_NEXT_JOB: { ALOGV("%s: Do next job", __func__); mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)pme->mDataQ.dequeue(); if (NULL != frame) { if (pme->mDataCB != NULL) { pme->mDataCB(frame, pme, pme->mUserData); } else { // no data cb routine, return buf here pme->bufDone(frame->bufs[0]->buf_idx); free(frame); } } } break; case CAMERA_CMD_TYPE_EXIT: ALOGD("%s: Exit", __func__); /* flush data buf queue */ pme->mDataQ.flush(); running = 0; break; default: break; } } while (running); ALOGV("%s: X", __func__); return NULL; }
static void *mm_camera_cmd_thread(void *data) { int running = 1; int ret; mm_camera_cmd_thread_t *cmd_thread = (mm_camera_cmd_thread_t *)data; mm_camera_cmdcb_t* node = NULL; do { do { ret = cam_sem_wait(&cmd_thread->cmd_sem); if (ret != 0 && errno != EINVAL) { CDBG_ERROR("%s: cam_sem_wait error (%s)", __func__, strerror(errno)); return NULL; } } while (ret != 0); /* we got notified about new cmd avail in cmd queue */ node = (mm_camera_cmdcb_t*)cam_queue_deq(&cmd_thread->cmd_queue); while (node != NULL) { switch (node->cmd_type) { case MM_CAMERA_CMD_TYPE_EVT_CB: case MM_CAMERA_CMD_TYPE_DATA_CB: case MM_CAMERA_CMD_TYPE_REQ_DATA_CB: case MM_CAMERA_CMD_TYPE_SUPER_BUF_DATA_CB: case MM_CAMERA_CMD_TYPE_CONFIG_NOTIFY: case MM_CAMERA_CMD_TYPE_START_ZSL: case MM_CAMERA_CMD_TYPE_STOP_ZSL: case MM_CAMERA_CMD_TYPE_GENERAL: case MM_CAMERA_CMD_TYPE_FLUSH_QUEUE: if (NULL != cmd_thread->cb) { cmd_thread->cb(node, cmd_thread->user_data); } break; case MM_CAMERA_CMD_TYPE_EXIT: default: running = 0; break; } free(node); node = (mm_camera_cmdcb_t*)cam_queue_deq(&cmd_thread->cmd_queue); } /* (node != NULL) */ } while (running); return NULL; }