add handling about broken msg from recv and apply the optimization of the audio msg 72/73272/4 accepted/tizen/ivi/20160609.091742 accepted/tizen/mobile/20160609.092002 accepted/tizen/tv/20160609.091619 accepted/tizen/wearable/20160609.091718 submit/tizen/20160609.040222
authorEunhae Choi <eunhae1.choi@samsung.com>
Tue, 7 Jun 2016 10:21:33 +0000 (19:21 +0900)
committerEunhae Choi <eunhae1.choi@samsung.com>
Wed, 8 Jun 2016 03:37:30 +0000 (12:37 +0900)
Change-Id: I94dbff36be95e6c7c4bea2901c17f0442bcdc00d

include/player_private.h
packaging/capi-media-player.spec
src/player.c
test/player_test.c

index 7870e83..aac2656 100644 (file)
@@ -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 {
index cd2c653..206c0cd 100644 (file)
@@ -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
index 703f431..888fac7 100644 (file)
@@ -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;
index 5bb7cd6..cf69c64 100644 (file)
@@ -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;