static int __mm_audio_stream_cb(MMCamcorderAudioStreamDataType *stream, void *user_param);
static int __mm_muxed_stream_cb(MMCamcorderMuxedStreamDataType *stream, void *user_param);
+static int __mm_video_encode_decision_cb(MMCamcorderVideoStreamDataType *stream, void *user_param);
static int __mm_recorder_msg_cb(int message, void *param, void *user_data);
}
+static int __mm_video_encode_decision_cb(MMCamcorderVideoStreamDataType *stream, void *user_param)
+{
+ recorder_s *handle = (recorder_s *)user_param;
+ int type = _RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION;
+ bool do_encode = true;
+
+ recorder_return_val_if_fail(handle && stream, 0);
+
+ if (!handle->user_cb[type]) {
+ LOGW("video_encode_decision_cb is NULL");
+ return true;
+ }
+
+ do_encode = ((recorder_video_encode_decision_cb)(handle->user_cb[type]))(stream, handle->user_data[type]);
+
+ LOGD("%d", do_encode);
+
+ return (int)do_encode;
+}
+
+
static int _recorder_check_and_set_attribute(recorder_h recorder, const char *attribute_name, int set_value)
{
bool reset_pipeline = false;
}
+int legacy_recorder_set_video_encode_decision_cb(recorder_h recorder, recorder_video_encode_decision_cb callback, void *user_data)
+{
+ int ret = MM_ERROR_NONE;
+ recorder_s *handle = (recorder_s *)recorder;
+ recorder_state_e state = RECORDER_STATE_NONE;
+
+ recorder_return_val_if_fail(handle && callback, RECORDER_ERROR_INVALID_PARAMETER);
+ recorder_return_val_if_fail(handle->camera_device_count > 0, RECORDER_ERROR_NOT_SUPPORTED);
+
+ legacy_recorder_get_state(recorder, &state);
+ recorder_return_val_if_fail(state <= RECORDER_STATE_READY, RECORDER_ERROR_INVALID_STATE);
+
+ ret = mm_camcorder_set_video_encode_decision_callback(handle->mm_handle, __mm_video_encode_decision_cb, handle);
+ if (ret == MM_ERROR_NONE) {
+ handle->user_cb[_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION] = callback;
+ handle->user_data[_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION] = user_data;
+ }
+
+ return __convert_recorder_error_code(__func__, ret);
+}
+
+
+int legacy_recorder_unset_video_encode_decision_cb(recorder_h recorder)
+{
+ int ret = MM_ERROR_NONE;
+ recorder_s *handle = (recorder_s *)recorder;
+ recorder_state_e state = RECORDER_STATE_NONE;
+
+ recorder_return_val_if_fail(handle, RECORDER_ERROR_INVALID_PARAMETER);
+ recorder_return_val_if_fail(handle->camera_device_count > 0, RECORDER_ERROR_NOT_SUPPORTED);
+
+ legacy_recorder_get_state(recorder, &state);
+ recorder_return_val_if_fail(state <= RECORDER_STATE_READY, RECORDER_ERROR_INVALID_STATE);
+
+ ret = mm_camcorder_set_video_encode_decision_callback(handle->mm_handle, NULL, NULL);
+ if (ret == MM_ERROR_NONE) {
+ handle->user_cb[_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION] = NULL;
+ handle->user_data[_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION] = NULL;
+ }
+
+ return __convert_recorder_error_code(__func__, ret);
+}
+
+
int legacy_recorder_set_error_cb(recorder_h recorder, recorder_error_cb callback, void *user_data)
{
recorder_s *handle = (recorder_s *)recorder;
tbm_fd fd;
} muse_recorder_export_data;
+typedef struct {
+ GList *list;
+ GMutex lock;
+ GCond cond;
+} muse_recorder_data_list;
+
/**
* @brief The structure type for the muse recorder.
*/
typedef struct {
recorder_h recorder_handle;
tbm_bufmgr bufmgr;
- GList *data_list;
GMutex list_lock;
+ muse_recorder_data_list recorder_data;
+ muse_camera_data_list camera_data;
+ bool video_encode_decision;
muse_recorder_type_e type;
} muse_recorder_handle_s;
export_data->bo = bo;
/* add bo info to list */
- g_mutex_lock(&muse_recorder->list_lock);
- muse_recorder->data_list = g_list_append(muse_recorder->data_list, (gpointer)export_data);
- g_mutex_unlock(&muse_recorder->list_lock);
+ g_mutex_lock(&muse_recorder->recorder_data.lock);
+ muse_recorder->recorder_data.list = g_list_append(muse_recorder->recorder_data.list, (gpointer)export_data);
+ g_mutex_unlock(&muse_recorder->recorder_data.lock);
/* send message */
muse_recorder_msg_event5_fd(MUSE_RECORDER_CB_EVENT,
export_data->bo = bo;
/* add bo info to list */
- g_mutex_lock(&muse_recorder->list_lock);
- muse_recorder->data_list = g_list_append(muse_recorder->data_list, (gpointer)export_data);
- g_mutex_unlock(&muse_recorder->list_lock);
+ g_mutex_lock(&muse_recorder->recorder_data.lock);
+ muse_recorder->recorder_data.list = g_list_append(muse_recorder->recorder_data.list, (gpointer)export_data);
+ g_mutex_unlock(&muse_recorder->recorder_data.lock);
/* send message */
muse_recorder_msg_event3_fd(MUSE_RECORDER_CB_EVENT,
return;
}
+bool _recorder_disp_video_encode_decision_cb(void *stream, void *user_data)
+{
+ int send_ret = 0;
+ char *send_message = NULL;
+ muse_recorder_handle_s *muse_recorder = NULL;
+ muse_camera_export_data *export_data = NULL;
+ muse_module_h module = (muse_module_h)user_data;
+ tbm_fd tfd[MUSE_NUM_FD] = {-1, -1, -1, -1};
+ gint64 end_time = 0;
+
+ /*LOGD("Enter");*/
+
+ muse_recorder = (muse_recorder_handle_s *)muse_server_ipc_get_handle(module);
+
+ recorder_return_val_if_fail(muse_recorder, true);
+
+ export_data = camera_export_data_new(stream, muse_recorder->bufmgr, tfd);
+ if (!export_data) {
+ LOGE("export_data failed");
+ return true;
+ }
+
+ /* add bo info to list */
+ g_mutex_lock(&muse_recorder->camera_data.lock);
+
+ muse_recorder->camera_data.list = g_list_append(muse_recorder->camera_data.list, (gpointer)export_data);
+
+ /* reset decision */
+ muse_recorder->video_encode_decision = true;
+
+ /* send message */
+ send_message = muse_core_msg_new(MUSE_RECORDER_CB_EVENT,
+ MUSE_TYPE_INT, PARAM_EVENT, MUSE_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION,
+ MUSE_TYPE_INT, PARAM_EVENT_CLASS, MUSE_CAMERA_EVENT_CLASS_THREAD_SUB,
+ MUSE_TYPE_INT, "video_fd", tfd[0],
+ MUSE_TYPE_INT, "num_buffer_fd", export_data->num_buffer_fd,
+ 0);
+
+ send_ret = muse_core_msg_send_fd(muse_server_module_get_msg_fd(module), (int *)tfd, send_message);
+
+ muse_core_msg_free(send_message);
+
+ end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND;
+ if (!g_cond_wait_until(&muse_recorder->camera_data.cond, &muse_recorder->camera_data.lock, end_time))
+ LOGW("video encode decision callback return message timeout");
+
+ g_mutex_unlock(&muse_recorder->camera_data.lock);
+
+ LOGD("returned video_encode_decision %d", muse_recorder->video_encode_decision);
+
+ return muse_recorder->video_encode_decision;
+}
+
bool _recorder_disp_foreach_supported_video_resolution_cb(int width, int height, void *user_data)
{
muse_module_h module = (muse_module_h)user_data;
return true;
}
-static int _recorder_remove_export_data(muse_module_h module, tbm_fd fd, int remove_all)
-{
- muse_recorder_handle_s *muse_recorder = NULL;
- GList *tmp_list = NULL;
- muse_recorder_export_data *export_data = NULL;
-
- recorder_return_val_if_fail(module && (fd >= 0 || remove_all), FALSE);
-
- muse_recorder = (muse_recorder_handle_s *)muse_server_ipc_get_handle(module);
- recorder_return_val_if_fail(muse_recorder, FALSE);
+static void _recorder_export_data_free(gpointer data)
+{
+ muse_recorder_export_data *export_data = (muse_recorder_export_data *)data;
- g_mutex_lock(&muse_recorder->list_lock);
+ if (!export_data)
+ return;
- tmp_list = muse_recorder->data_list;
+ LOGD("fd[%d], bo[%p]", export_data->fd, export_data->bo);
- while (tmp_list) {
- export_data = (muse_recorder_export_data *)tmp_list->data;
+ /* unref bo */
+ if (export_data->bo) {
+ tbm_bo_unref(export_data->bo);
+ export_data->bo = NULL;
+ } else {
+ LOGW("bo for fd[%d] is NULL", export_data->fd);
+ }
- tmp_list = tmp_list->next;
+ /* close exported fd */
+ if (export_data->fd > -1) {
+ /*LOGD("close export_data->fd %d", export_data->fd);*/
+ close(export_data->fd);
+ export_data->fd = -1;
+ }
- if (export_data == NULL) {
- LOGW("NULL data");
- continue;
- }
+ g_free(export_data);
+}
- if (export_data->fd != fd && remove_all == FALSE)
- continue;
- /*LOGD("fd %d matched, remove it (remove_all %d)", fd, remove_all);*/
+static int _recorder_export_data_compare(gconstpointer data, gconstpointer fd_to_find)
+{
+ LOGD("%d : %d", ((muse_recorder_export_data *)data)->fd, GPOINTER_TO_INT(fd_to_find));
+ return (((muse_recorder_export_data *)data)->fd != GPOINTER_TO_INT(fd_to_find));
+}
- if (export_data->bo) {
- tbm_bo_unref(export_data->bo);
- export_data->bo = NULL;
- } else {
- LOGW("bo for fd %d is NULL", fd);
- }
- /* close exported fd */
- close(export_data->fd);
- export_data->fd = -1;
+static gboolean _recorder_remove_export_data(muse_recorder_data_list *recorder_data, tbm_fd fd)
+{
+ GList *found_item = NULL;
- muse_recorder->data_list = g_list_remove(muse_recorder->data_list, export_data);
+ recorder_return_val_if_fail(recorder_data, FALSE);
+ recorder_return_val_if_fail(fd >= -1, FALSE); /* -1 means "Remove all". */
- g_free(export_data);
- export_data = NULL;
+ g_mutex_lock(&recorder_data->lock);
- if (remove_all == FALSE) {
- /*LOGD("fd %d, remove done", fd);*/
- g_mutex_unlock(&muse_recorder->list_lock);
- return TRUE;
- } else {
- LOGD("check next data");
+ if (fd == -1) {
+ g_list_free_full(recorder_data->list, _recorder_export_data_free);
+ recorder_data->list = NULL;
+ } else {
+ found_item = g_list_find_custom(recorder_data->list,
+ GINT_TO_POINTER(fd), _recorder_export_data_compare);
+ if (!found_item) {
+ LOGE("could not find data for fd[%d]", fd);
+ g_mutex_unlock(&recorder_data->lock);
+ return FALSE;
}
- }
- g_mutex_unlock(&muse_recorder->list_lock);
+ recorder_data->list = g_list_remove_link(recorder_data->list, found_item);
+ g_list_free_full(found_item, _recorder_export_data_free);
+ }
- if (remove_all)
- LOGD("remove all done");
- else
- LOGE("should not be reached here - fd %d", fd);
+ g_mutex_unlock(&recorder_data->lock);
- return FALSE;
+ return TRUE;
}
muse_recorder = g_new0(muse_recorder_handle_s, 1);
muse_recorder->type = recorder_type;
- g_mutex_init(&muse_recorder->list_lock);
+ g_mutex_init(&muse_recorder->recorder_data.lock);
+ g_cond_init(&muse_recorder->recorder_data.cond);
+ g_mutex_init(&muse_recorder->camera_data.lock);
+ g_cond_init(&muse_recorder->camera_data.cond);
if (muse_server_ipc_get_bufmgr(&muse_recorder->bufmgr) != MM_ERROR_NONE ||
muse_server_ipc_get_gdbus_connection((GDBusConnection **)&gdbus_connection) != MM_ERROR_NONE) {
muse_recorder->recorder_handle = NULL;
}
- g_mutex_clear(&muse_recorder->list_lock);
+ g_cond_init(&muse_recorder->camera_data.cond);
+ g_mutex_init(&muse_recorder->camera_data.lock);
+ g_cond_init(&muse_recorder->recorder_data.cond);
+ g_mutex_init(&muse_recorder->recorder_data.lock);
+
g_free(muse_recorder);
LOGE("error 0x%x", ret);
ret = legacy_recorder_destroy(muse_recorder->recorder_handle);
if (ret == RECORDER_ERROR_NONE) {
- _recorder_remove_export_data(module, 0, TRUE);
+ _recorder_remove_export_data(&muse_recorder->recorder_data, -1);
+ camera_remove_export_data(&muse_recorder->camera_data, -1);
- g_mutex_clear(&muse_recorder->list_lock);
+ g_cond_clear(&muse_recorder->camera_data.cond);
+ g_mutex_clear(&muse_recorder->camera_data.lock);
+ g_cond_clear(&muse_recorder->recorder_data.cond);
+ g_mutex_clear(&muse_recorder->recorder_data.lock);
muse_recorder->bufmgr = NULL;
int recorder_dispatcher_return_buffer(muse_module_h module)
{
int ret_fd = -1;
+ int video_encode_decision = 1;
+ muse_recorder_buffer_type_e buffer_type = MUSE_RECORDER_BUFFER_TYPE_AUDIO_STREAM;
muse_recorder_handle_s *muse_recorder = NULL;
muse_recorder = (muse_recorder_handle_s *)muse_server_ipc_get_handle(module);
recorder_return_val_if_fail(muse_recorder, MUSE_RECORDER_ERROR_NONE);
muse_recorder_msg_get(ret_fd, muse_server_module_get_msg(module));
+ muse_recorder_msg_get(buffer_type, muse_server_module_get_msg(module));
+
+ /*LOGD("handle[%p] buffer type[%d] ret_fd[%d]", muse_recorder, buffer_type, ret_fd);*/
+
+ if (buffer_type == MUSE_RECORDER_BUFFER_TYPE_VIDEO_ENCODE_DECISION) {
+ /* get decision and send signal */
+ muse_recorder_msg_get(video_encode_decision, muse_server_module_get_msg(module));
- /*LOGD("handle : %p, ret_fd : %d", muse_recorder, ret_fd);*/
+ g_mutex_lock(&muse_recorder->camera_data.lock);
+ muse_recorder->video_encode_decision = (bool)video_encode_decision;
+ /*LOGD("video_encode_decision[%d]", video_encode_decision);*/
+ g_cond_signal(&muse_recorder->camera_data.cond);
+ g_mutex_unlock(&muse_recorder->camera_data.lock);
- if (!_recorder_remove_export_data(module, (tbm_fd)ret_fd, FALSE))
- LOGE("remove export data failed : fd %d", ret_fd);
+ if (!camera_remove_export_data(&muse_recorder->camera_data, (tbm_fd)ret_fd))
+ LOGE("remove export data for video encode decision failed. fd[%d]", ret_fd);
+ } else {
+ if (!_recorder_remove_export_data(&muse_recorder->recorder_data, (tbm_fd)ret_fd))
+ LOGE("remove export data failed. buffer type[%d] fd[%d]", buffer_type, ret_fd);
+ }
return MUSE_RECORDER_ERROR_NONE;
}
}
+int recorder_dispatcher_set_video_encode_decision_cb(muse_module_h module)
+{
+ int ret = RECORDER_ERROR_NONE;
+ muse_recorder_api_e api = MUSE_RECORDER_API_SET_VIDEO_ENCODE_DECISION_CB;
+ muse_recorder_api_class_e class = MUSE_RECORDER_API_CLASS_IMMEDIATE;
+ muse_recorder_handle_s *muse_recorder = NULL;
+
+ muse_recorder = (muse_recorder_handle_s *)muse_server_ipc_get_handle(module);
+
+ recorder_send_msg_return_err_if_fail(muse_recorder, RECORDER_ERROR_INVALID_OPERATION, MUSE_RECORDER_ERROR_NONE);
+
+ ret = legacy_recorder_set_video_encode_decision_cb(muse_recorder->recorder_handle,
+ (recorder_video_encode_decision_cb)_recorder_disp_video_encode_decision_cb, (void *)module);
+
+ muse_recorder_msg_return(api, class, ret, module);
+
+ return MUSE_RECORDER_ERROR_NONE;
+}
+
+
+int recorder_dispatcher_unset_video_encode_decision_cb(muse_module_h module)
+{
+ int ret = RECORDER_ERROR_NONE;
+ muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_MUXED_STREAM_CB;
+ muse_recorder_api_class_e class = MUSE_RECORDER_API_CLASS_IMMEDIATE;
+ muse_recorder_handle_s *muse_recorder = NULL;
+
+ muse_recorder = (muse_recorder_handle_s *)muse_server_ipc_get_handle(module);
+
+ recorder_send_msg_return_err_if_fail(muse_recorder, RECORDER_ERROR_INVALID_OPERATION, MUSE_RECORDER_ERROR_NONE);
+
+ ret = legacy_recorder_unset_video_encode_decision_cb(muse_recorder->recorder_handle);
+
+ muse_recorder_msg_return(api, class, ret, module);
+
+ return MUSE_RECORDER_ERROR_NONE;
+}
+
+
int (*dispatcher[MUSE_RECORDER_API_MAX]) (muse_module_h module) = {
recorder_dispatcher_create, /* MUSE_RECORDER_API_CREATE */
recorder_dispatcher_destroy, /* MUSE_RECORDER_API_DESTROY */
recorder_dispatcher_set_muxed_stream_cb, /* MUSE_RECORDER_API_SET_MUXED_STREAM_CB */
recorder_dispatcher_unset_muxed_stream_cb, /* MUSE_RECORDER_API_UNSET_MUXED_STREAM_CB */
recorder_dispatcher_set_interrupt_started_cb, /* MUSE_RECORDER_API_SET_INTERRUPT_STARTED_CB */
- recorder_dispatcher_unset_interrupt_started_cb /* MUSE_RECORDER_API_UNSET_INTERRUPT_STARTED_CB */
+ recorder_dispatcher_unset_interrupt_started_cb, /* MUSE_RECORDER_API_UNSET_INTERRUPT_STARTED_CB */
+ recorder_dispatcher_set_video_encode_decision_cb, /* MUSE_RECORDER_API_SET_VIDEO_ENCODE_DECISION_CB */
+ recorder_dispatcher_unset_video_encode_decision_cb /* MUSE_RECORDER_API_UNSET_VIDEO_ENCODE_DECISION_CB */
};
case RECORDER_STATE_CREATED:
ret = legacy_recorder_destroy(muse_recorder->recorder_handle);
if (ret == RECORDER_ERROR_NONE) {
- _recorder_remove_export_data(module, 0, TRUE);
+ _recorder_remove_export_data(&muse_recorder->recorder_data, -1);
+ camera_remove_export_data(&muse_recorder->camera_data, -1);
- g_mutex_clear(&muse_recorder->list_lock);
+ g_cond_clear(&muse_recorder->camera_data.cond);
+ g_mutex_clear(&muse_recorder->camera_data.lock);
+ g_cond_clear(&muse_recorder->recorder_data.cond);
+ g_mutex_clear(&muse_recorder->recorder_data.lock);
muse_recorder->bufmgr = NULL;