From 6843f98d69cab05ee2d0ffff85a787b7e7127639 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Tue, 7 Jun 2016 19:21:33 +0900 Subject: [PATCH] add handling about broken msg from recv and apply the optimization of the audio msg Change-Id: I94dbff36be95e6c7c4bea2901c17f0442bcdc00d --- include/player_private.h | 1 + packaging/capi-media-player.spec | 2 +- src/player.c | 205 +++++++++++++++++++++++---------------- test/player_test.c | 2 +- 4 files changed, 125 insertions(+), 85 deletions(-) diff --git a/include/player_private.h b/include/player_private.h index 7870e83..aac2656 100644 --- a/include/player_private.h +++ b/include/player_private.h @@ -59,6 +59,7 @@ typedef struct { gchar *recvMsg; gint recved; ret_msg_s *retMsgHead; + gchar *part_of_msg; /* keep msg till we receive the hole msg */ } msg_buff_s; typedef struct _player_data { diff --git a/packaging/capi-media-player.spec b/packaging/capi-media-player.spec index cd2c653..206c0cd 100644 --- a/packaging/capi-media-player.spec +++ b/packaging/capi-media-player.spec @@ -3,7 +3,7 @@ Name: capi-media-player Summary: A Media Player API -Version: 0.3.8 +Version: 0.3.9 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/player.c b/src/player.c index 703f431..888fac7 100644 --- a/src/player.c +++ b/src/player.c @@ -292,24 +292,64 @@ static void _del_mem(player_cli_s * player) } } -static int player_recv_msg(callback_cb_info_s * cb_info, int len) +static int player_recv_msg(callback_cb_info_s * cb_info) { - int recvLen; + int recvLen = 0; msg_buff_s *buff = &cb_info->buff; - char *new; - if (len && buff->bufLen - MUSE_MSG_MAX_LENGTH <= len) { - LOGD("realloc Buffer %d -> %d, Msg Length %d", buff->bufLen, buff->bufLen + MUSE_MSG_MAX_LENGTH, len); - buff->bufLen += MUSE_MSG_MAX_LENGTH; - new = g_renew(char, buff->recvMsg, buff->bufLen); - if (new && new != buff->recvMsg) - buff->recvMsg = new; + memset(buff->recvMsg, 0x00, sizeof(char)*buff->bufLen); + recvLen = muse_core_ipc_recv_msg(cb_info->fd, buff->recvMsg); + + /* check the first msg */ + if (buff->part_of_msg && buff->recvMsg[0] != '{') + { + gchar *tmp = strndup(buff->recvMsg, recvLen); + if (!tmp) { + LOGE("failed to copy msg."); + return 0; + } + + LOGD("get remained part of msg %d + %d, %d", recvLen, strlen(buff->part_of_msg), buff->bufLen); + + /* realloc buffer */ + if (recvLen+strlen(buff->part_of_msg) >= buff->bufLen) { + LOGD("realloc Buffer %d -> %d", buff->bufLen, recvLen+strlen(buff->part_of_msg)+1); + buff->bufLen = recvLen+strlen(buff->part_of_msg)+1; + buff->recvMsg = g_renew(char, buff->recvMsg, buff->bufLen); + if (!buff->recvMsg) { + LOGE("failed renew buffer."); + if (tmp) + free(tmp); + return 0; + } + memset(buff->recvMsg, 0x00, sizeof(char)*buff->bufLen); + } + sprintf(buff->recvMsg, "%s%s", buff->part_of_msg, tmp); + recvLen += strlen(buff->part_of_msg); + + free(buff->part_of_msg); + buff->part_of_msg = NULL; + free(tmp); + tmp = NULL; } - recvLen = muse_core_ipc_recv_msg(cb_info->fd, buff->recvMsg + len); - len += recvLen; + /* check the last msg */ + if (buff->recvMsg[recvLen-1] != '}') { + char *part_pos = strrchr(buff->recvMsg, '}'); + int part_len = ((part_pos) ? (strlen(part_pos+1)) : (0)); + + if (part_len > 0) { + buff->part_of_msg = strndup(part_pos+1, part_len); + if (!buff->part_of_msg) { + LOGE("failed to alloc buffer for part of msg."); + return 0; + } + LOGD("get part of msg: %d, %s", strlen(buff->part_of_msg), buff->part_of_msg); + recvLen -= part_len; + } + } - return len; + return recvLen; } static void set_null_user_cb(callback_cb_info_s * cb_info, muse_player_event_e event) @@ -622,43 +662,35 @@ static void __media_packet_video_frame_cb_handler(callback_cb_info_s * cb_info, static void __audio_frame_cb_handler(callback_cb_info_s * cb_info, char *recvMsg) { - unsigned char *data = NULL; - unsigned int size = 0; tbm_bo bo = NULL; tbm_bo_handle thandle; tbm_key key = 0; player_audio_raw_data_s audio; - void *audio_frame = &audio; - bool ret = TRUE; - - player_msg_get2_array(recvMsg, size, INT, key, INT, audio_frame, ret); - if (ret) { - bo = tbm_bo_import(cb_info->bufmgr, key); - if (bo == NULL) { - LOGE("TBM get error : bo is NULL, key:%d", key); - goto EXIT; - } - thandle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE | TBM_OPTION_READ); - if (thandle.ptr == NULL) { - LOGE("TBM get error : handle pointer is NULL"); - goto EXIT; - } + if (!player_msg_get(key, recvMsg)) { + LOGE("failed to get value from msg."); + return; + } - data = g_new(unsigned char, size); - if (data) { - memcpy(data, thandle.ptr, size); - audio.data = data; - audio.size = size; - LOGD("user callback data %p, size %d", audio.data, audio.size); - ((player_audio_pcm_extraction_cb) cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME]) (&audio, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME]); - g_free(data); - } else - LOGE("g_new failure"); + bo = tbm_bo_import(cb_info->bufmgr, key); + if (bo == NULL) { + LOGE("TBM get error : bo is NULL, key:%d", key); + goto EXIT; + } - tbm_bo_unmap(bo); + thandle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE | TBM_OPTION_READ); + if (thandle.ptr == NULL) { + LOGE("TBM get error : handle pointer is NULL"); + goto EXIT; } + memcpy(&audio, thandle.ptr, sizeof(player_audio_raw_data_s)); + audio.data = thandle.ptr + sizeof(player_audio_raw_data_s); + + LOGD("user callback data %p, size %d", audio.data, audio.size); + ((player_audio_pcm_extraction_cb) cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME]) (&audio, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME]); + tbm_bo_unmap(bo); + EXIT: if (bo) tbm_bo_unref(bo); @@ -1023,57 +1055,61 @@ static void *client_cb_handler(gpointer data) int parse_len = 0; int offset = 0; callback_cb_info_s *cb_info = data; - char *recvMsg = cb_info->buff.recvMsg; + char *recvMsg = NULL; muse_core_msg_parse_err_e err; while (g_atomic_int_get(&cb_info->running)) { len = 0; err = MUSE_MSG_PARSE_ERROR_NONE; - do { - len = player_recv_msg(cb_info, len); - if (len <= 0) - break; - recvMsg[len] = '\0'; - parse_len = len; - offset = 0; - while (offset < len) { - api = MUSE_PLAYER_API_MAX; - void *jobj = muse_core_msg_json_object_new(recvMsg + offset, &parse_len, &err); - if (jobj) { - if (muse_core_msg_json_object_get_value("api", jobj, &api, MUSE_TYPE_INT)) { - if (api < MUSE_PLAYER_API_MAX) { - g_mutex_lock(&cb_info->player_mutex); - cb_info->buff.recved++; - _add_ret_msg(api, cb_info, offset, parse_len); - g_cond_signal(&cb_info->player_cond[api]); - g_mutex_unlock(&cb_info->player_mutex); - if (api == MUSE_PLAYER_API_DESTROY) - g_atomic_int_set(&cb_info->running, 0); - } else if (api == MUSE_PLAYER_CB_EVENT) { - int event; - char *buffer; - g_mutex_lock(&cb_info->player_mutex); - buffer = strndup(recvMsg + offset, parse_len); - g_mutex_unlock(&cb_info->player_mutex); - if (muse_core_msg_json_object_get_value("event", jobj, &event, MUSE_TYPE_INT)) - _user_callback_handler(cb_info, event, buffer); - } - } else { - LOGE("Failed to get value. offset:%d/%d, [msg][ %s ]", offset, len, (recvMsg+offset)); + + len = player_recv_msg(cb_info); + if (len <= 0) + break; + + recvMsg = cb_info->buff.recvMsg; + recvMsg[len] = '\0'; + + parse_len = len; + offset = 0; + while (offset < len) { + api = MUSE_PLAYER_API_MAX; +// LOGD(">>>>>> [%d/%d] %p, %s", offset, len, recvMsg + offset, recvMsg + offset); +// usleep(10*1000); + + void *jobj = muse_core_msg_json_object_new(recvMsg + offset, &parse_len, &err); + if (jobj) { + if (muse_core_msg_json_object_get_value("api", jobj, &api, MUSE_TYPE_INT)) { + if (api < MUSE_PLAYER_API_MAX) { + g_mutex_lock(&cb_info->player_mutex); + cb_info->buff.recved++; + _add_ret_msg(api, cb_info, offset, parse_len); + g_cond_signal(&cb_info->player_cond[api]); + g_mutex_unlock(&cb_info->player_mutex); + if (api == MUSE_PLAYER_API_DESTROY) + g_atomic_int_set(&cb_info->running, 0); + } else if (api == MUSE_PLAYER_CB_EVENT) { + int event; + char *buffer; + g_mutex_lock(&cb_info->player_mutex); + buffer = strndup(recvMsg + offset, parse_len); + g_mutex_unlock(&cb_info->player_mutex); + if (muse_core_msg_json_object_get_value("event", jobj, &event, MUSE_TYPE_INT)) + _user_callback_handler(cb_info, event, buffer); } - muse_core_msg_json_object_free(jobj); } else { - LOGE("Failed to get msg obj. err:%d", err); + LOGE("Failed to get value. offset:%d/%d, [msg][ %s ]", offset, len, (recvMsg+offset)); } - - if (parse_len == 0) - break; - offset += parse_len; - parse_len = len - offset; + muse_core_msg_json_object_free(jobj); + } else { + LOGE("Failed to get msg obj. err:%d", err); } - } while (err == MUSE_MSG_PARSE_ERROR_CONTINUE); - if (len <= 0) - break; + + if (parse_len == 0 || err != MUSE_MSG_PARSE_ERROR_NONE) + break; + + offset += parse_len; + parse_len = len - offset; + } } if (g_atomic_int_get(&cb_info->running)) _notify_disconnected(cb_info); @@ -1105,6 +1141,7 @@ static callback_cb_info_s *callback_new(gint sockfd) buff->bufLen = MUSE_MSG_MAX_LENGTH + 1; buff->recved = 0; buff->retMsgHead = NULL; + buff->part_of_msg = NULL; g_atomic_int_set(&cb_info->running, 1); cb_info->fd = sockfd; @@ -1138,6 +1175,8 @@ static void callback_destroy(callback_cb_info_s * cb_info) g_mutex_clear(&cb_info->seek_cb_mutex); g_free(cb_info->buff.recvMsg); + if (cb_info->buff.part_of_msg) + g_free(cb_info->buff.part_of_msg); g_free(cb_info); } @@ -2333,7 +2372,7 @@ int player_get_album_art(player_h player, void **palbum_art, int *psize) goto EXIT; } - if (muse_core_msg_json_object_get_value("size", jobj, &size, MUSE_TYPE_INT) && size>0) { + if (muse_core_msg_json_object_get_value("size", jobj, &size, MUSE_TYPE_INT) && (size > 0)) { LOGD("size : %d", size); if (!muse_core_msg_json_object_get_value("key", jobj, &key, MUSE_TYPE_INT)) { ret = PLAYER_ERROR_INVALID_OPERATION; diff --git a/test/player_test.c b/test/player_test.c index 5bb7cd6..cf69c64 100644 --- a/test/player_test.c +++ b/test/player_test.c @@ -64,7 +64,7 @@ static media_format_h g_video_fmt = NULL; static int _save(unsigned char *src, int length); -#define DUMP_OUTBUF 0 +#define DUMP_OUTBUF 1 #if DUMP_OUTBUF FILE *fp_out1 = NULL; FILE *fp_out2 = NULL; -- 2.7.4