/** * Function: module_imgbase_client_enqueue_streambuf * * Description: function to enqueue stream buffer * * Arguments: * @p_client - IMGLIB_BASE client * @p_meta - pointer to the meta * @prop: image properties * * Return values: * none * * Notes: none **/ static void module_imgbase_client_enqueue_streambuf( imgbase_client_t *p_client, img_meta_t *p_meta, cam_stream_img_prop_t *prop) { cam_stream_parm_buffer_t *p_stream_buf = calloc(1, sizeof(cam_stream_parm_buffer_t)); if (p_stream_buf && p_meta) { p_stream_buf->imgProp = *prop; p_stream_buf->type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP; IDBG_HIGH("%s:%d] (%d %d %d %d) (%d %d) (%d %d)", __func__, __LINE__, p_stream_buf->imgProp.crop.left, p_stream_buf->imgProp.crop.top, p_stream_buf->imgProp.crop.width, p_stream_buf->imgProp.crop.height, p_stream_buf->imgProp.input.width, p_stream_buf->imgProp.input.height, p_stream_buf->imgProp.output.width, p_stream_buf->imgProp.output.height); if (IMG_ERROR(img_q_enqueue(&p_client->stream_parm_q, p_stream_buf))) { free(p_stream_buf); p_stream_buf = NULL; } } }
/** * Function: module_imgbase_client_destroy * * Description: This function is used to destroy the imgbase client * * Arguments: * @p_client: imgbase client * * Return values: * imaging error values * * Notes: none **/ void module_imgbase_client_destroy(imgbase_client_t *p_client) { int rc = IMG_SUCCESS; img_component_ops_t *p_comp = NULL; if (NULL == p_client) { return; } p_comp = &p_client->comp; IDBG_MED("%s:%d] state %d", __func__, __LINE__, p_client->state); if (IMGLIB_STATE_STARTED == p_client->state) { module_imgbase_client_stop(p_client); } if (IMGLIB_STATE_INIT == p_client->state) { rc = IMG_COMP_DEINIT(p_comp); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] deinit failed %d", __func__, __LINE__, rc); } p_client->state = IMGLIB_STATE_IDLE; } if (IMGLIB_STATE_IDLE == p_client->state) { img_q_deinit(&p_client->stream_parm_q); pthread_mutex_destroy(&p_client->mutex); pthread_cond_destroy(&p_client->cond); free(p_client); p_client = NULL; } IDBG_MED("%s:%d] X", __func__, __LINE__); }
int load_image(shooter_ctx* ctx, char *name, asset** a) { SDL_Surface* loadedImage = NULL; int ret; *a = malloc(sizeof(**a)); if (!(*a)) return (ENOMEM); loadedImage = IMG_Load(name); if (loadedImage != NULL) { (*a)->texture = SDL_CreateTextureFromSurface(ctx->renderer, loadedImage); SDL_FreeSurface(loadedImage); } else { IMG_ERROR("IMG_Load"); return (1); } if (!((*a)->texture)) { SDL_ERROR("SDL_CreateTextureFromSurface"); return (1); } ret = SDL_QueryTexture((*a)->texture, NULL, NULL, &((*a)->sx), &((*a)->sy)); if (ret) { SDL_ERROR("SDL_QueryTexture"); return (ret); } return (0); }
/** * Function: module_imglib_send_msg * * Description: This method is used to send message to the * message thread * * Input parameters: * p_msg_th - The pointer to message thread * p_msg - pointer to the message * * Return values: * IMG_SUCCESS * * Notes: none **/ int module_imglib_send_msg(mod_imglib_msg_th_t *p_msg_th, mod_img_msg_t *p_msg) { int status = IMG_SUCCESS; mod_img_msg_t *p_msg_new; IDBG_MED("%s:%d] E", __func__, __LINE__); /* create message */ p_msg_new = (mod_img_msg_t *)malloc(sizeof(mod_img_msg_t)); if (NULL == p_msg_new) { IDBG_ERROR("%s:%d] cannot create message", __func__, __LINE__); return IMG_ERR_NO_MEMORY; } memcpy(p_msg_new, p_msg, sizeof(mod_img_msg_t)); status = img_q_enqueue(&p_msg_th->msg_q, p_msg_new); if (IMG_ERROR(status)) { IDBG_ERROR("%s:%d] cannot enqueue message", __func__, __LINE__); free(p_msg_new); return status; } img_q_signal(&p_msg_th->msg_q); IDBG_MED("%s:%d] X", __func__, __LINE__); return status; }
/** * Function: module_imgbase_client_handle_outbuf_done * * Description: Function to handle output buf done event * * Arguments: * @p_client - IMGLIB_BASE client * @p_frame - frame for buf done * @buf_done - flag to indicate if the buf done needs to be * called * * Return values: * none * * Notes: none **/ static void module_imgbase_client_handle_outbuf_done( imgbase_client_t *p_client, img_frame_t *p_frame, int8_t buf_done) { int rc = IMG_SUCCESS; int *p_frame_id; boolean ret; if (!p_client || !p_frame) { IDBG_ERROR("%s:%d] Error", __func__, __LINE__); return; } module_imgbase_t *p_mod = (module_imgbase_t *)p_client->p_mod; p_frame_id = (int *)p_frame->private_data; IDBG_MED("%s:%d] buffer idx %d frame_id %d", __func__, __LINE__, p_frame->idx, *p_frame_id); if (!p_frame_id) { IDBG_ERROR("%s:%d] Error", __func__, __LINE__); return; } if (p_client->p_srcport) { /* ToDo */ } else if (!p_mod->caps.inplace_algo) { IDBG_MED("%s:%d] Buffer %d %x %d %d", __func__, __LINE__, p_mod->subdevfd, p_client->identity, p_frame->idx, *p_frame_id); rc = module_imglib_common_release_buffer(p_mod->subdevfd, p_client->identity, p_frame->idx, *p_frame_id, buf_done); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] Error getting output buffer %d", __func__, __LINE__, p_frame->idx); } } end: if (p_frame) { free(p_frame); } }
/** * Function: module_imgbase_client_start * * Description: This function is used to start the IMGLIB_BASE * client * * Arguments: * @p_client: IMGLIB_BASE client * * Return values: * imaging error values * * Notes: none **/ int module_imgbase_client_start(imgbase_client_t *p_client) { int rc = IMG_SUCCESS; img_component_ops_t *p_comp = &p_client->comp; pthread_mutex_lock(&p_client->mutex); p_client->stream_on = TRUE; rc = IMG_COMP_START(p_comp, NULL); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] start failed %d", __func__, __LINE__, rc); pthread_mutex_unlock(&p_client->mutex); return rc; } p_client->state = IMGLIB_STATE_STARTED; pthread_mutex_unlock(&p_client->mutex); return rc; }
/** * Function: module_imgbase_client_stop * * Description: This function is used to stop the IMGLIB_BASE * client * * Arguments: * @p_client: IMGLIB_BASE client * * Return values: * imaging error values * * Notes: none **/ int module_imgbase_client_stop(imgbase_client_t *p_client) { int rc = IMG_SUCCESS; img_component_ops_t *p_comp = &p_client->comp; pthread_mutex_lock(&p_client->mutex); p_client->stream_on = FALSE; rc = IMG_COMP_ABORT(p_comp, NULL); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] create failed %d", __func__, __LINE__, rc); pthread_mutex_unlock(&p_client->mutex); return rc; } p_client->state = IMGLIB_STATE_INIT; img_q_flush_and_destroy(&p_client->stream_parm_q); pthread_mutex_unlock(&p_client->mutex); return rc; }
/** * Function: module_imgbase_client_get_frame * * Description: This function is to fetching the output buffer * based in buffer info * Arguments: * @p_appdata: imgbase client * @pframe: frame pointer * * Return values: * imaging error values * * Notes: none **/ int module_imgbase_client_get_frame(void *p_appdata, img_frame_t **pp_frame) { int rc = IMG_SUCCESS; assert(p_appdata != NULL); assert(pp_frame != NULL); *pp_frame = NULL; imgbase_client_t *p_client = (imgbase_client_t *)p_appdata; img_frame_t *p_out_frame; uint8_t *l_frameid; IDBG_HIGH("%s:%d] E", __func__, __LINE__); uint8_t *poutframeinfo = (uint8_t *)calloc(1, sizeof(img_frame_t) + sizeof(int)); if (!poutframeinfo) { IDBG_ERROR("%s:%d] Error: Cannot allocate memory", __func__, __LINE__); rc = IMG_ERR_NO_MEMORY; goto error; } p_out_frame = (img_frame_t *)poutframeinfo; l_frameid = p_out_frame->private_data = (uint8_t *)poutframeinfo + sizeof(img_frame_t); /* Queue output buffer */ rc = module_imgbase_client_get_outputbuf(p_client, p_out_frame); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); goto error; } *l_frameid = p_client->frame_id; *pp_frame = p_out_frame; return rc; error: if (poutframeinfo) { free(poutframeinfo); } return rc; }
/** * Function: faceproc_comp_get_param * * Description: Gets faceproc parameters * * Input parameters: * handle - The pointer to the component handle. * param - The type of the parameter * p_data - The pointer to the paramter structure. The structure * for each paramter type will be defined in denoise.h * * Return values: * IMG_SUCCESS * IMG_ERR_INVALID_OPERATION * IMG_ERR_INVALID_INPUT * * Notes: none **/ int faceproc_comp_get_param(void *handle, img_param_type param, void *p_data) { faceproc_comp_t *p_comp = (faceproc_comp_t *)handle; int status = IMG_SUCCESS; status = p_comp->b.ops.get_parm(&p_comp->b, param, p_data); if (status < 0) return status; switch (param) { case QWD_FACEPROC_RESULT: { faceproc_result_t *p_result = (faceproc_result_t *)p_data; if (NULL == p_result) { IDBG_ERROR("%s:%d] invalid faceproc result", __func__, __LINE__); return IMG_ERR_INVALID_INPUT; } if (!p_comp->width || !p_comp->height) { IDBG_ERROR("%s:%d] frame not processed", __func__, __LINE__); return IMG_ERR_INVALID_INPUT; } status = faceproc_comp_eng_get_output(p_comp, p_result); if (IMG_ERROR(status)) { IDBG_ERROR("%s:%d] invalid faceproc result", __func__, __LINE__); return status; } p_result->trans_info.h_scale = p_comp->trans_info.h_scale; p_result->trans_info.v_scale = p_comp->trans_info.v_scale; p_result->trans_info.h_offset = p_comp->trans_info.h_offset; p_result->trans_info.v_offset = p_comp->trans_info.v_offset; break; } default: IDBG_ERROR("%s:%d] Error", __func__, __LINE__); return IMG_ERR_INVALID_INPUT; } return IMG_SUCCESS; }
/** * Function: faceproc_comp_deinit * * Description: Un-initializes the face processing component * * Input parameters: * handle - The pointer to the component handle. * * Return values: * IMG_SUCCESS * IMG_ERR_INVALID_OPERATION * * Notes: none **/ int faceproc_comp_deinit(void *handle) { faceproc_comp_t *p_comp = (faceproc_comp_t *)handle; int status = IMG_SUCCESS; IDBG_MED("%s:%d] ", __func__, __LINE__); status = faceproc_comp_abort(handle, NULL); if (status < 0) return status; status = p_comp->b.ops.deinit(&p_comp->b); if (status < 0) return status; status = faceproc_comp_eng_destroy(p_comp); if (IMG_ERROR(status)) { IDBG_ERROR("%s:%d] failed", __func__, __LINE__); return status; } free(p_comp); return IMG_SUCCESS; }
/** * Function: faceproc_comp_abort * * Description: Aborts the execution of faceproc * * Input parameters: * handle - The pointer to the component handle. * p_data - The pointer to the command structure. The structure * for each command type is defined in denoise.h * * Return values: * IMG_SUCCESS * * Notes: none **/ int faceproc_comp_abort(void *handle, void *p_data) { faceproc_comp_t *p_comp = (faceproc_comp_t *)handle; img_component_t *p_base = (img_component_t *)handle; int status = IMG_SUCCESS; IDBG_HIGH("%s:%d] state %d", __func__, __LINE__, p_base->state); pthread_mutex_lock(&p_base->mutex); if (IMG_STATE_STARTED != p_base->state) { pthread_mutex_unlock(&p_base->mutex); return IMG_SUCCESS; } p_base->state = IMG_STATE_STOP_REQUESTED; pthread_mutex_unlock(&p_base->mutex); /*signal the thread*/ img_q_signal(&p_base->inputQ); if (!pthread_equal(pthread_self(), p_base->threadid)) { IDBG_MED("%s:%d] thread id %d %d", __func__, __LINE__, (uint32_t)pthread_self(), (uint32_t)p_base->threadid); pthread_join(p_base->threadid, NULL); } /* destroy the handle */ status = faceproc_comp_eng_destroy(p_comp); if (IMG_ERROR(status)) { IDBG_ERROR("%s:%d] failed", __func__, __LINE__); return status; } pthread_mutex_lock(&p_base->mutex); p_base->state = IMG_STATE_INIT; pthread_mutex_unlock(&p_base->mutex); IDBG_HIGH("%s:%d] X", __func__, __LINE__); return status; }
/** module_imgbase_init: * * Arguments: * @name - name of the module * @comp_role: imaging component role * @comp_name: imaging component name * @mod_private: derived structure pointer * @p_caps: imaging capability * @lib_name: library name * @feature_mask: feature mask of imaging algo * @p_modparams: module parameters * * Description: This function is used to initialize the imgbase * module * * Return values: * MCTL module instance pointer * * Notes: none **/ mct_module_t *module_imgbase_init(const char *name, img_comp_role_t comp_role, char *comp_name, void *mod_private, img_caps_t *p_caps, char *lib_name, uint32_t feature_mask, module_imgbase_params_t *p_modparams) { mct_module_t *p_mct_mod = NULL; module_imgbase_t *p_mod = NULL; img_core_ops_t *p_core_ops = NULL; mct_port_t *p_sinkport = NULL, *p_sourceport = NULL; int rc = 0; int i = 0; if (!name || !comp_name || (comp_role >= IMG_COMP_ROLE_MAX) || !p_caps || !lib_name || (0 == feature_mask)) { IDBG_ERROR("%s:%d invalid input", __func__, __LINE__); return NULL; } IDBG_MED("%s:%d] ", __func__, __LINE__); p_mct_mod = mct_module_create(name); if (NULL == p_mct_mod) { IDBG_ERROR("%s:%d cannot allocate mct module", __func__, __LINE__); return NULL; } p_mod = malloc(sizeof(module_imgbase_t)); if (NULL == p_mod) { IDBG_ERROR("%s:%d failed", __func__, __LINE__); goto error; } p_mct_mod->module_private = (void *)p_mod; memset(p_mod, 0, sizeof(module_imgbase_t)); pthread_mutex_init(&p_mod->mutex, NULL); pthread_cond_init(&p_mod->cond, NULL); p_core_ops = &p_mod->core_ops; IDBG_MED("%s:%d] ", __func__, __LINE__); /* check if the imgbase module is present */ rc = img_core_get_comp(comp_role, comp_name, p_core_ops); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] Error rc %d", __func__, __LINE__, rc); goto error; } /* try to load the component */ rc = IMG_COMP_LOAD(p_core_ops, lib_name); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] Error rc %d", __func__, __LINE__, rc); goto error; } p_mod->lib_ref_count++; p_mod->imgbase_client = NULL; p_mod->mod_private = mod_private; p_mod->caps = *p_caps; p_mod->subdevfd = -1; p_mod->feature_mask = feature_mask; if (p_modparams) p_mod->modparams = *p_modparams; IDBG_MED("%s:%d] ", __func__, __LINE__); /* create static ports */ for (i = 0; i < MAX_IMGLIB_BASE_STATIC_PORTS; i++) { p_sinkport = module_imgbase_create_port(p_mct_mod, MCT_PORT_SINK); if (NULL == p_sinkport) { IDBG_ERROR("%s:%d] create SINK port failed", __func__, __LINE__); goto error; } p_sourceport = module_imgbase_create_port(p_mct_mod, MCT_PORT_SRC); if (NULL == p_sourceport) { IDBG_ERROR("%s:%d] create SINK port failed", __func__, __LINE__); goto error; } } p_mct_mod->start_session = module_imgbase_start_session; p_mct_mod->stop_session = module_imgbase_stop_session; p_mct_mod->query_mod = module_imgbase_query_mod; IDBG_MED("%s:%d] %p", __func__, __LINE__, p_mct_mod); return p_mct_mod; error: if (p_mod) { module_imgbase_deinit(p_mct_mod); } else if (p_mct_mod) { mct_module_destroy(p_mct_mod); p_mct_mod = NULL; } return NULL; }
/** Function: module_imgbase_client_create * * Description: This function is used to create the IMGLIB_BASE client * * Arguments: * @p_mct_mod: mct module pointer * @p_port: mct port pointer * @identity: identity of the stream * @stream_info: stream information * * Return values: * imaging error values * * Notes: none **/ int module_imgbase_client_create(mct_module_t *p_mct_mod, mct_port_t *p_port, uint32_t identity, mct_stream_info_t *stream_info) { int rc = IMG_SUCCESS; imgbase_client_t *p_client = NULL; img_component_ops_t *p_comp = NULL; img_core_ops_t *p_core_ops = NULL; module_imgbase_t *p_mod = (module_imgbase_t *)p_mct_mod->module_private; mct_list_t *p_temp_list = NULL; img_frame_ops_t l_frameops = { module_imgbase_client_get_frame, module_imgbase_client_release_frame, NULL }; img_init_params_t init_params; memset(&init_params, 0x0, sizeof(img_init_params_t)); img_init_params_t *p_params = NULL; /* set init params */ if (p_mod->modparams.imgbase_client_init_params) { p_params = &init_params; p_mod->modparams.imgbase_client_init_params(p_params); } p_core_ops = &p_mod->core_ops; IDBG_MED("%s:%d]", __func__, __LINE__); p_client = (imgbase_client_t *)malloc(sizeof(imgbase_client_t)); if (NULL == p_client) { IDBG_ERROR("%s:%d] IMGLIB_BASE client alloc failed", __func__, __LINE__); return IMG_ERR_NO_MEMORY; } /* initialize the variables */ memset(p_client, 0x0, sizeof(imgbase_client_t)); p_comp = &p_client->comp; pthread_mutex_init(&p_client->mutex, NULL); pthread_cond_init(&p_client->cond, NULL); p_client->state = IMGLIB_STATE_IDLE; p_client->stream_info = stream_info; img_q_init(&p_client->stream_parm_q, "stream_parm_q"); rc = IMG_COMP_CREATE(p_core_ops, p_comp); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] create failed %d", __func__, __LINE__, rc); goto error; } rc = IMG_COMP_INIT(p_comp, p_client, p_params); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] init failed %d", __func__, __LINE__, rc); goto error; } p_client->state = IMGLIB_STATE_INIT; rc = IMG_COMP_SET_CB(p_comp, module_imgbase_client_event_handler); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); goto error; } rc = IMG_COMP_SET_PARAM(p_comp, QIMG_PARAM_CAPS, &p_mod->caps); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); goto error; } l_frameops.p_appdata = p_client; rc = IMG_COMP_SET_PARAM(p_comp, QIMG_PARAM_FRAME_OPS, &l_frameops); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); goto error; } /* add the client to the list */ p_temp_list = mct_list_append(p_mod->imgbase_client, p_client, NULL, NULL); if (NULL == p_temp_list) { IDBG_ERROR("%s:%d] list append failed", __func__, __LINE__); rc = IMG_ERR_NO_MEMORY; goto error; } p_mod->imgbase_client = p_temp_list; p_client->p_sinkport = p_port; p_client->identity = identity; p_client->parent_mod = p_mod->parent_mod ? p_mod->parent_mod : p_mct_mod; p_client->p_mod = p_mod; p_port->port_private = p_client; IDBG_HIGH("%s:%d] port %p client %p X", __func__, __LINE__, p_port, p_client); return rc; error: if (p_client) { module_imgbase_client_destroy(p_client); p_client = NULL; } return rc; }
/** * Function: module_faceproc_stab_filter * * Description: Stabilization it will stabilize the entry * based on reference entry it self, if reference is passed * coordinates change will be detected from them * * Arguments: * @history - History for this entry * @stab_params - Stabilization parameters * @refer: Reference coordinates for stabilization * @threshold: Variation threshold * 0 - Face is stable when previous face is equal with new * 1 - Face is stable when previous face is bigger then new * 2 - Face is stable when previous face is smaller then new * * Return values: * IMG error codes **/ static int module_faceproc_stab_filter(faceproc_history_holder_t *history, fd_face_stab_params_t *stab_params, faceproc_history_entry_t *refer, uint32_t threshold) { faceproc_history_state_t new_state; boolean within_limit = FALSE; boolean face_stable = FALSE; uint32_t last_index; int ret = IMG_SUCCESS; if (history->faces_inside == 1) { IDBG_MED("%s:%d] not enough faces skip", __func__, __LINE__); return IMG_SUCCESS; } /* Do nothing if previous coordinates are the same as new * Sometimes stabilization is executed twice for same results */ last_index = (history->index + history->faces_inside - 1) % history->faces_inside; if ((history->entry[history->index].x != history->entry[last_index].x || history->entry[history->index].y != history->entry[last_index].y) && (history->entry[history->index].x == history->stable_entry.x && history->entry[history->index].y == history->stable_entry.y)) { IDBG_MED("%s:%d] Stabilization executed twice", __func__, __LINE__); return 0; } /* If there is refer for stabilization use it */ if (FD_STAB_STATE_STABILIZE != history->state) { if (refer) { within_limit = module_faceproc_within_limit(refer, &history->stable_refer, threshold); } else { within_limit = module_faceproc_within_limit(&history->entry[history->index], &history->stable_entry, threshold); } } new_state = history->state; switch (history->state) { case FD_STAB_STATE_UNSTABLE: if (history->state_count >= history->max_state_count) { new_state = FD_STAB_STATE_STABILIZE; } else if (TRUE == within_limit) { new_state = FD_STAB_STATE_STABLE; } break; case FD_STAB_STATE_STABLE: if (TRUE == within_limit) { if (module_faceproc_stab_is_continues(stab_params->mode)) { face_stable = module_faceproc_stab_is_stable(history, refer, stab_params->mode); if (FALSE == face_stable) { history->stable_entry.x = history->entry[history->index].x; history->stable_entry.y = history->entry[history->index].y; } } break; } else if (history->max_state_count) { new_state = FD_STAB_STATE_UNSTABLE; break; } else { /* do not brake here go to stabilize state directly */ new_state = FD_STAB_STATE_STABILIZE; } case FD_STAB_STATE_STABILIZE: face_stable = module_faceproc_stab_is_stable(history, refer, stab_params->mode); /* If face is stabilized put to the stable state */ if (face_stable) { if (refer) { history->stable_refer = *refer; } new_state = FD_STAB_STATE_STABLE; } else { history->state_count = 0; } ret = module_faceproc_apply_filter(stab_params, &history->stable_entry, &history->entry[history->index]); if (IMG_ERROR(ret)) { IDBG_ERROR("Can not apply filter"); goto out; } break; default: ret = IMG_ERR_GENERAL; IDBG_ERROR("Error invalid state something went wrong"); goto out; } /* Change state if requested */ if (new_state != history->state) { history->state = new_state; history->state_count = 0; } else { history->state_count++; } out: return ret; }
/** * Function: module_faceproc_faces_stabilization * * Description: Function to faces stabilization * * Arguments: * @p_client - Face proc client * @p_result - Face detection result on which filter will be applied * * Return values: * none * * Notes: none **/ int module_faceproc_faces_stabilization(faceproc_client_t *p_client, faceproc_result_t *p_result) { cam_face_detection_data_t faces_data; faceproc_stabilization_t *stab; faceproc_history_entry_t refer; faceproc_history_entry_t eyes_center; faceproc_history_entry_t *p_refer; uint32_t i, j, new_faces, threshold, eyes_distance; int position; int ret = IMG_SUCCESS; if (!p_client || !p_result) { IDBG_ERROR("%s:%d]Invalid input", __func__, __LINE__); return IMG_ERR_INVALID_INPUT; } stab = &p_client->stabilization; if (!p_result->num_faces_detected) { IDBG_MED("%s:%d] no faces reset the histories", __func__, __LINE__); stab->detected_faces = 0; return IMG_SUCCESS; } /* Sort the output ROI */ qsort(p_result->roi, p_result->num_faces_detected, sizeof(p_result->roi[0]), module_faceproc_stab_roi_sort_pos); i = 0, j = 0; while (i < p_result->num_faces_detected) { /* If there are new faces put them them in history */ if (i >= stab->detected_faces) { module_faceproc_stab_init_face(&stab->faces[j++], &p_result->roi[i++], p_client->p_fd_chromatix); stab->detected_faces++; continue; } /* Check boundary limit */ position = module_faceproc_stab_check_face(&p_result->roi[i], &stab->faces[j]); if (FACEPROC_FACE_SAME == position) { module_faceproc_stab_add_face(&stab->faces[j++], &p_result->roi[i++], p_client->p_fd_chromatix); } else if (FACEPROC_FACE_BEFORE == position) { /* Move the faces to the right if it is not the last element */ if (i < (p_result->num_faces_detected - 1)) { memcpy(&stab->faces[j + 1], &stab->faces[j], sizeof(stab->faces[0]) * (stab->detected_faces - j)); stab->detected_faces++; } /* Put the new face in place */ module_faceproc_stab_init_face(&stab->faces[j++], &p_result->roi[i++], p_client->p_fd_chromatix); } else if (FACEPROC_FACE_AFTER == position) { /* Move faces to the left and remove current */ memcpy(&stab->faces[j], &stab->faces[j + 1], sizeof(stab->faces[0]) * stab->detected_faces - j); stab->detected_faces--; } } if (stab->detected_faces > p_result->num_faces_detected) { stab->detected_faces = p_result->num_faces_detected; } /* Stabilize faces */ memset(&refer, 0x00, sizeof(refer)); for (i = 0; i < p_result->num_faces_detected; i++) { /* Get eyes distance and center they will be used as reference */ eyes_distance = FD_STAB_CALC_DISTANCE(p_result->roi[i].fp.face_pt[FACE_PART_LEFT_EYE], p_result->roi[i].fp.face_pt[FACE_PART_RIGHT_EYE]); eyes_center.x = (p_result->roi[i].fp.face_pt[FACE_PART_LEFT_EYE].x + p_result->roi[i].fp.face_pt[FACE_PART_RIGHT_EYE].x) / 2; eyes_center.y = (p_result->roi[i].fp.face_pt[FACE_PART_LEFT_EYE].y + p_result->roi[i].fp.face_pt[FACE_PART_RIGHT_EYE].y) / 2; /* Stabilize face size */ if (p_client->p_fd_chromatix->stab_size.enable) { p_refer = NULL; if (p_client->p_fd_chromatix->stab_size.use_reference) { refer.x = eyes_distance; refer.y = eyes_distance; p_refer = &refer; threshold = FD_STAB_CALC_THRESHOLD(eyes_distance, p_client->p_fd_chromatix->stab_size.threshold); } else { threshold = FD_STAB_CALC_THRESHOLD(stab->faces[i].face_size.stable_entry.x, p_client->p_fd_chromatix->stab_size.threshold); } ret = module_faceproc_stab_filter(&stab->faces[i].face_size, &p_client->p_fd_chromatix->stab_size, p_refer, threshold); if (IMG_ERROR(ret)) { IDBG_ERROR("Can not apply face size filter"); goto out; } /* Fill stable face size */ p_result->roi[i].face_boundary.dx = stab->faces[i].face_size.stable_entry.x; p_result->roi[i].face_boundary.dy = stab->faces[i].face_size.stable_entry.y; } /* Stabilize face position */ if (p_client->p_fd_chromatix->stab_pos.enable) { p_refer = NULL; if (p_client->p_fd_chromatix->stab_pos.use_reference) { refer.x = eyes_center.x; refer.y = eyes_center.y; p_refer = &refer; } threshold = FD_STAB_CALC_THRESHOLD(p_client->main_dim.width, p_client->p_fd_chromatix->stab_pos.threshold); ret = module_faceproc_stab_filter(&stab->faces[i].face_position, &p_client->p_fd_chromatix->stab_pos, p_refer, threshold); if (IMG_ERROR(ret)) { IDBG_ERROR("Can not apply face position filter"); goto out; } /* Fill stable face position */ p_result->roi[i].face_boundary.x = stab->faces[i].face_position.stable_entry.x - (p_result->roi[i].face_boundary.dx / 2); p_result->roi[i].face_boundary.y = stab->faces[i].face_position.stable_entry.y - (p_result->roi[i].face_boundary.dy / 2); } /* Stabilize mouth */ if (p_client->p_fd_chromatix->stab_mouth.enable) { p_refer = NULL; if (p_client->p_fd_chromatix->stab_mouth.use_reference) { refer.x = eyes_center.x; refer.y = eyes_center.y; p_refer = &refer; } threshold = FD_STAB_CALC_THRESHOLD(p_client->main_dim.width, p_client->p_fd_chromatix->stab_mouth.threshold); ret = module_faceproc_stab_filter(&stab->faces[i].mouth_position, &p_client->p_fd_chromatix->stab_mouth, p_refer, threshold); if (IMG_ERROR(ret)) { IDBG_ERROR("Can not apply mouth position filter"); goto out; } /* Fill stable face mouth */ p_result->roi[i].fp.face_pt[FACE_PART_MOUTH].x = stab->faces[i].mouth_position.stable_entry.x; p_result->roi[i].fp.face_pt[FACE_PART_MOUTH].y = stab->faces[i].mouth_position.stable_entry.y; } /* Stabilize smile */ if (p_client->p_fd_chromatix->stab_smile.enable) { p_refer = NULL; if (p_client->p_fd_chromatix->stab_smile.use_reference) { refer.x = eyes_center.x; refer.y = eyes_center.y; p_refer = &refer; } threshold = FD_STAB_CALC_THRESHOLD(p_client->main_dim.width, p_client->p_fd_chromatix->stab_smile.threshold); ret = module_faceproc_stab_filter(&stab->faces[i].smile_degree, &p_client->p_fd_chromatix->stab_smile, p_refer, threshold); if (IMG_ERROR(ret)) { IDBG_ERROR("Can not apply smile degree filter"); goto out; } p_result->roi[i].sm.smile_degree = stab->faces[i].smile_degree.stable_entry.x; } } out: return ret; }
/** module_cac_init: * * Arguments: * @name - name of the module * * Description: This function is used to initialize the cac * module * * Return values: * MCTL module instance pointer * * Notes: none **/ mct_module_t *module_cac_init(const char *name) { mct_module_t *p_mct_mod = NULL; module_cac_t *p_mod = NULL; img_core_ops_t *p_core_ops = NULL; mct_port_t *p_sinkport = NULL, *p_sourceport = NULL; int rc = 0; int i = 0; IDBG_MED("%s:%d] ", __func__, __LINE__); p_mct_mod = mct_module_create(name); if (NULL == p_mct_mod) { IDBG_ERROR("%s:%d cannot allocate mct module", __func__, __LINE__); return NULL; } p_mod = malloc(sizeof(module_cac_t)); if (NULL == p_mod) { IDBG_ERROR("%s:%d failed", __func__, __LINE__); goto error; } p_mct_mod->module_private = (void *)p_mod; memset(p_mod, 0, sizeof(module_cac_t)); pthread_mutex_init(&p_mod->mutex, NULL); pthread_cond_init(&p_mod->cond, NULL); p_core_ops = &p_mod->core_ops; IDBG_MED("%s:%d] ", __func__, __LINE__); /* check if the cac module is present */ rc = img_core_get_comp(IMG_COMP_CAC, "qcom.cac", p_core_ops); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] Error rc %d", __func__, __LINE__, rc); goto error; } /* try to load the component */ rc = IMG_COMP_LOAD(p_core_ops, NULL); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] Error rc %d", __func__, __LINE__, rc); goto error; } p_mod->lib_ref_count++; p_mod->cac_client = NULL; IDBG_MED("%s:%d] ", __func__, __LINE__); /* create static ports */ for (i = 0; i < MAX_CAC_STATIC_PORTS; i++) { p_sinkport = module_cac_create_port(p_mct_mod, MCT_PORT_SINK); if (NULL == p_sinkport) { IDBG_ERROR("%s:%d] create SINK port failed", __func__, __LINE__); goto error; } p_sourceport = module_cac_create_port(p_mct_mod, MCT_PORT_SRC); if (NULL == p_sourceport) { IDBG_ERROR("%s:%d] create SINK port failed", __func__, __LINE__); goto error; } } p_mct_mod->start_session = module_cac_start_session; p_mct_mod->stop_session = module_cac_stop_session; IDBG_MED("%s:%d] %p", __func__, __LINE__, p_mct_mod); return p_mct_mod; error: if (p_mod) { module_cac_deinit(p_mct_mod); } else if (p_mct_mod) { mct_module_destroy(p_mct_mod); p_mct_mod = NULL; } return NULL; }
/** * Function: module_imgbase_client_handle_buffer * * Description: This function is used to handle the divert * buffer event * * Arguments: * @p_client: IMGLIB_BASE client * @p_buf_divert: Buffer divert structure * * Return values: * imaging error values * * Notes: none **/ int module_imgbase_client_handle_buffer(imgbase_client_t *p_client, isp_buf_divert_t *p_buf_divert) { int rc = IMG_SUCCESS; img_component_ops_t *p_comp = &p_client->comp; img_frame_t *p_frame, *p_out_frame; isp_buf_divert_t *l_buf_divert; module_imgbase_t *p_mod = (module_imgbase_t *)p_client->p_mod; uint8_t *poutframeinfo = NULL; uint8_t *pframeinfo = NULL; int *l_frameid; int frame_id; img_meta_t *p_meta = NULL; IDBG_LOW("%s:%d] ", __func__, __LINE__); pframeinfo = (uint8_t *)calloc(1, sizeof(img_frame_t) + sizeof(isp_buf_divert_t)); if (!pframeinfo) { IDBG_ERROR("%s:%d] Error: Cannot allocate memory", __func__, __LINE__); return IMG_ERR_NO_MEMORY; } p_frame = (img_frame_t *)pframeinfo; l_buf_divert = (isp_buf_divert_t *)(pframeinfo + sizeof(img_frame_t)); *l_buf_divert = *p_buf_divert; p_frame->private_data = l_buf_divert; // Get Frame rc = module_imgbase_client_getbuf(p_client, l_buf_divert, p_frame, l_buf_divert->native_buf); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] Error: Cannot get frame", __func__, __LINE__); free(pframeinfo); rc = IMG_ERR_GENERAL; goto error; } frame_id = p_buf_divert->buffer.sequence; IDBG_HIGH("%s:%d] dim %dx%d id %d", __func__, __LINE__, p_frame->info.width, p_frame->info.height, frame_id); rc = IMG_COMP_Q_BUF(p_comp, p_frame, IMG_IN); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); goto error; } p_client->cur_buf_cnt++; /* Send output buffer */ if (p_client->cur_buf_cnt >= p_mod->caps.num_input) { poutframeinfo = (uint8_t *)calloc(1, sizeof(img_frame_t) + sizeof(int)); if (!poutframeinfo) { IDBG_ERROR("%s:%d] Error: Cannot allocate memory", __func__, __LINE__); rc = IMG_ERR_NO_MEMORY; goto error; } p_out_frame = (img_frame_t *)poutframeinfo; l_frameid = p_out_frame->private_data = (uint8_t *)poutframeinfo + sizeof(img_frame_t); /* Queue output buffer */ rc = module_imgbase_client_get_outputbuf(p_client, p_out_frame); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); goto error; } *l_frameid = frame_id; /* queue the buffer */ rc = IMG_COMP_Q_BUF(p_comp, p_out_frame, IMG_OUT); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); goto error; } /* Send meta buffer */ p_meta = (img_meta_t *)calloc(1, sizeof(img_meta_t)); if (!p_meta) { IDBG_ERROR("%s:%d] Error: Cannot allocate memory", __func__, __LINE__); rc = IMG_ERR_NO_MEMORY; goto error; } IDBG_MED("%s:%d] p_meta %p", __func__, __LINE__, p_meta); p_client->current_meta.zoom_factor = module_imglib_common_get_zoom_ratio( p_client->parent_mod, p_client->stream_info->reprocess_config.pp_feature_config.zoom_level); *p_meta = p_client->current_meta; p_client->p_current_meta = p_meta; /* queue the meta buffer */ rc = IMG_COMP_Q_META_BUF(p_comp, p_meta); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); goto error; } } IDBG_MED("%s:%d] X", __func__, __LINE__); return 0; error: if (pframeinfo) { free(pframeinfo); } if (poutframeinfo) { free(poutframeinfo); } if (p_meta) { free(p_meta); } return rc; }
/** * Function: faceproc_test_init * * Description: init FaceProc test case * * Input parameters: * p_test - test object * * Return values: * IMG_SUCCESS * IMG_ERR_GENERAL * * Notes: none **/ int faceproc_test_init(faceproc_test_t *p_test) { int rc = IMG_SUCCESS; img_param_type param; img_component_ops_t *p_comp = &p_test->base->comp; img_core_ops_t *p_core_ops = &p_test->base->core_ops; p_test->mode = FACE_DETECT; p_test->config.frame_cfg.max_width = MAX_WIDTH; p_test->config.frame_cfg.max_height = MAX_HEIGHT; p_test->config.histogram_enable = FALSE; p_test->config.face_cfg.min_face_size = MIN_FACE_SIZE; p_test->config.face_cfg.max_face_size = 1500; p_test->config.face_cfg.max_num_face_to_detect = 2; p_test->config.face_cfg.face_orientation_hint = FD_FACE_ORIENTATION_UNKNOWN; p_test->config.face_cfg.rotation_range = 45; p_test->config.histogram_enable = 0; p_test->config.fd_feature_mask = FACE_PROP_DEFAULT; p_test->test_chromatix = &g_test_chromatix; rc = img_core_get_comp(IMG_COMP_FACE_PROC, "qcom.faceproc", p_core_ops); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); return rc; } rc = IMG_COMP_LOAD(p_core_ops, NULL); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); return rc; } rc = IMG_COMP_CREATE(p_core_ops, p_comp); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); return rc; } rc = IMG_COMP_INIT(p_comp, (void *)p_test, NULL); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); return rc; } rc = IMG_COMP_SET_CB(p_comp, faceproc_test_event_handler); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); return rc; } rc = IMG_COMP_SET_PARAM(p_comp, QWD_FACEPROC_MODE, (void *)&p_test->mode); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); return rc; } rc = IMG_COMP_SET_PARAM(p_comp, QWD_FACEPROC_CFG, (void *)&p_test->config); if (rc != IMG_SUCCESS) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); return rc; } rc = IMG_COMP_SET_PARAM(p_comp, QWD_FACEPROC_CHROMATIX, (void *)p_test->test_chromatix); if (IMG_ERROR(rc)) { IDBG_ERROR("%s:%d] rc %d", __func__, __LINE__, rc); return rc; } return 0; }
/** * Function: face_proc_thread_loop * * Description: Main algorithm thread loop * * Input parameters: * data - The pointer to the component object * * Return values: * NULL * * Notes: none **/ void *face_proc_thread_loop(void *handle) { faceproc_comp_t *p_comp = (faceproc_comp_t *)handle; img_component_t *p_base = &p_comp->b; int status = IMG_SUCCESS; img_frame_t *p_frame = NULL; img_event_t event; int i = 0, count; img_frame_t ds_frame; img_frame_t *p_ds_frame = &ds_frame; IDBG_MED("%s:%d] state %d abort %d", __func__, __LINE__, p_base->state, p_comp->abort_flag); #ifdef FD_DROP_FRAME while (1) { /* wait for frame */ img_q_wait_for_signal(&p_base->inputQ, face_proc_can_wait, p_comp); if (!face_proc_can_wait(p_comp)) { IDBG_HIGH("%s:%d] Exit the thread", __func__, __LINE__); break; } p_comp->facedrop_cnt = 0; p_frame = (img_frame_t *)img_q_get_last_entry(&p_base->inputQ, face_proc_release_frame, p_comp); if (NULL == p_frame) { IDBG_ERROR("%s:%d] No more elements.", __func__, __LINE__); continue; } IDBG_MED("%s:%d] frame drop cnt %d q_cnt %d buf_idx %d", __func__, __LINE__, p_comp->facedrop_cnt, img_q_count(&p_base->inputQ), p_frame->idx); #else while ((p_frame = img_q_wait(&p_base->inputQ, face_proc_can_wait, p_comp)) != NULL) { #endif p_comp->width = FD_WIDTH(p_frame); p_comp->height = FD_HEIGHT(p_frame); if (!FD_DS_ENABLE(p_comp)) { status = faceproc_comp_eng_exec(p_comp, p_frame); } else { status = face_proc_get_scaled_frame(p_comp, p_frame, p_ds_frame); if (IMG_SUCCEEDED(status)) { status = faceproc_comp_eng_exec(p_comp, p_ds_frame); free(FD_ADDR(p_ds_frame)); } } if (status != 0) { IDBG_ERROR("%s:%d] frameproc exec error %d", __func__, __LINE__, status); status = img_q_enqueue(&p_base->outputQ, p_frame); if (status < 0) { IDBG_ERROR("%s:%d] enqueue error %d", __func__, __LINE__, status); } else { IMG_SEND_EVENT(p_base, QIMG_EVT_BUF_DONE); } IMG_SEND_EVENT(p_base, QIMG_EVT_ERROR); continue; } IDBG_MED("%s:%d] state %d abort %d", __func__, __LINE__, p_base->state, p_comp->abort_flag); IMG_CHK_ABORT_RET_LOCKED(p_base, &p_base->mutex); status = img_q_enqueue(&p_base->outputQ, p_frame); if (status != 0) { IDBG_ERROR("%s:%d] enqueue error %d", __func__, __LINE__, status); } else { IMG_SEND_EVENT(p_base, QIMG_EVT_BUF_DONE); } IMG_SEND_EVENT(p_base, QIMG_EVT_FACE_PROC); } IDBG_MED("%s:%d] state %d abort %d", __func__, __LINE__, p_base->state, p_comp->abort_flag); pthread_mutex_lock(&p_base->mutex); p_base->state = IMG_STATE_STOPPED; pthread_mutex_unlock(&p_base->mutex); IMG_SEND_EVENT(p_base, QIMG_EVT_DONE); return IMG_SUCCESS; error: /* flush rest of the buffers */ count = img_q_count(&p_base->inputQ); IDBG_MED("%s:%d] Error buf count %d", __func__, __LINE__, count); for (i = 0; i < count; i++) { p_frame = img_q_dequeue(&p_base->inputQ); if (NULL == p_frame) { IDBG_ERROR("%s:%d] invalid buffer", __func__, __LINE__); continue; } status = img_q_enqueue(&p_base->outputQ, p_frame); if (status != 0) { IDBG_ERROR("%s:%d] enqueue error %d", __func__, __LINE__, status); continue; } IMG_SEND_EVENT(p_base, QIMG_EVT_BUF_DONE); } pthread_mutex_lock(&p_base->mutex); p_base->state = IMG_STATE_STOPPED; pthread_mutex_unlock(&p_base->mutex); IMG_SEND_EVENT_PYL(p_base, QIMG_EVT_ERROR, status, status); return NULL; } /** * Function: faceproc_comp_start * * Description: Start the execution of faceproc * * Input parameters: * handle - The pointer to the component handle. * p_data - The pointer to the command structure. The structure * for each command type will be defined in denoise.h * * Return values: * IMG_SUCCESS * IMG_ERR_INVALID_OPERATION * IMG_ERR_GENERAL * * Notes: none **/ int faceproc_comp_start(void *handle, void *p_data) { faceproc_comp_t *p_comp = (faceproc_comp_t *)handle; img_component_t *p_base = &p_comp->b; int status = IMG_SUCCESS; pthread_mutex_lock(&p_base->mutex); if ((p_base->state != IMG_STATE_INIT) || (NULL == p_base->thread_loop)) { IDBG_ERROR("%s:%d] Error state %d", __func__, __LINE__, p_base->state); pthread_mutex_unlock(&p_base->mutex); return IMG_ERR_NOT_SUPPORTED; } if (!p_comp->config_set) { IDBG_ERROR("%s:%d] error config not set", __func__, __LINE__); pthread_mutex_unlock(&p_base->mutex); return status; } faceproc_comp_cfg_debug(&p_comp->config); faceproc_comp_chromaitix_debug(&p_comp->fd_chromatix); status = faceproc_comp_eng_config(p_comp); if (IMG_ERROR(status)) { IDBG_ERROR("%s:%d] failed", __func__, __LINE__); pthread_mutex_unlock(&p_base->mutex); return status; } IMG_CHK_ABORT_UNLK_RET(p_base, &p_base->mutex); /* flush the queues */ img_q_flush(&p_base->inputQ); img_q_flush(&p_base->outputQ); pthread_mutex_unlock(&p_base->mutex); status = p_comp->b.ops.start(&p_comp->b, p_data); if (status < 0) return status; return status; }