/**
 * 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__);

}
Beispiel #3
0
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;
}
Beispiel #9
0
/**
 * 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;
}
Beispiel #10
0
/**
 * 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;
}
Beispiel #11
0
/**
 * 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;
}
Beispiel #12
0
/** 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;
}
Beispiel #18
0
/**
 * 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;
}
Beispiel #19
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;
}