90686b2e0fc46a585f9888402fc14240f33dd42d
[platform/core/api/player.git] / src / player.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sched.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <syscall.h>
24 #include <inttypes.h>
25 #include <unistd.h>
26 #include <tbm_bufmgr.h>
27 #include <tbm_surface.h>
28 #include <tbm_surface_internal.h>
29 #include <dlog.h>
30 #include <mm_error.h>
31 #include <muse_core.h>
32 #include <muse_client.h>
33 #include <muse_player.h>
34 #include <muse_player_msg.h>
35 #include <sound_manager.h>
36 #include <sound_manager_internal.h>
37 #include <storage-internal.h>
38 #include <system_info.h>
39 #include "player_internal.h"
40 #include "player_private.h"
41 #include "player_msg.h"
42
43 #define INVALID_MUSE_TYPE_VALUE 0
44 #define MAX_S_PATH_LEN 32
45 #define MODULE_NAME                      "player"
46 #define PLAYER_FEATURE_SOUND_STREAM      "http://tizen.org/feature/multimedia.player.stream_info"
47 #define PLAYER_FEATURE_OPENGL            "http://tizen.org/feature/opengles.version.2_0"
48 #define PLAYER_FEATURE_SPHERICAL_VIDEO   "http://tizen.org/feature/multimedia.player.spherical_video"
49 #define PLAYER_FEATURE_AUDIO_OFFLOAD     "http://tizen.org/feature/multimedia.player.audio_offload"
50 #ifndef M_PI
51 #define M_PI  3.14159265358979323846
52 #endif
53
54 typedef struct {
55         tbm_fd tfd[MUSE_NUM_FD];
56         char *buffer;
57 } _player_recv_data;
58
59 typedef struct {
60         int int_data;
61         callback_cb_info_s *cb_info;
62         _player_recv_data *recv_data;
63 } _player_cb_data;
64
65 typedef struct {
66         intptr_t remote_v_data;
67         gint fd;
68         gint fd_id;
69         bool use_tsurf_pool;
70 } _media_pkt_video_fin_data;
71
72 typedef struct {
73         gint key;
74         gint fd;
75         gint fd_id;
76         tbm_bo bo;
77 } _media_pkt_audio_fin_data;
78
79 static int _player_deinit_memory_buffer(player_cli_s *pc);
80 static void _player_event_queue_add(player_event_queue *ev, _player_cb_data *data);
81 static bool _player_need_sync_context(int event_id);
82 static void _player_remove_idle_event(callback_cb_info_s *cb_info, muse_player_event_e event_type, bool remove_all);
83 typedef void (*player_retrieve_buffer_cb)(void *user_data);
84 static void __retrieve_buffer_cb(void *user_data);
85 static void __player_media_packet_video_decoded_cb(media_packet_h packet, void *user_data);
86 static int __player_set_retrieve_buffer_cb(player_h player, player_retrieve_buffer_cb callback, void *user_data);
87 static int __player_unset_retrieve_buffer_cb(player_h player);
88 static void _player_release_internal_memory(player_cli_s *pc, bool deinit_server_mem);
89
90 /*
91 * Internal Implementation
92 */
93 int _player_send_msg(muse_player_api_e api, player_cli_s *player, char *msg, tbm_fd tfd, char **retbuf)
94 {
95         int ret = PLAYER_ERROR_NONE;
96         int send_len = 0;
97         int send_fd = INVALID_DEFAULT_VALUE;
98         int send_tfd[MUSE_NUM_FD];
99         int timeout = client_get_api_timeout(player, api);
100
101         memset(send_tfd, INVALID_DEFAULT_VALUE, sizeof(send_tfd));
102
103         if (player && CALLBACK_INFO(player)) {
104                 send_fd = MSG_FD(player);
105         } else {
106                 LOGE("can not access to cb_info");
107                 return PLAYER_ERROR_INVALID_STATE;
108         }
109
110         if ((send_fd <= 0) || !muse_core_fd_is_valid(send_fd)) {
111                 LOGE("invalid socket fd %d", send_fd);
112                 return PLAYER_ERROR_INVALID_OPERATION;
113         }
114
115         if (tfd != INVALID_DEFAULT_VALUE) {
116                 send_tfd[0] = tfd;
117                 send_len = muse_core_msg_send_fd(send_fd, send_tfd, msg);
118         } else {
119                 send_len = muse_core_msg_send(send_fd, msg);
120         }
121         if (send_len <= 0) {
122                 LOGE("sending message failed");
123                 return PLAYER_ERROR_INVALID_OPERATION;
124         } else {
125                 ret = client_wait_for_cb_return(api, CALLBACK_INFO(player), retbuf, timeout);
126         }
127
128         return ret;
129 }
130
131 int _player_send_msg_async(int send_fd, char *msg)
132 {
133         int send_len = 0;
134
135         if ((send_fd <= 0) || !muse_core_fd_is_valid(send_fd)) {
136                 LOGE("invalid socket fd %d", send_fd);
137                 return PLAYER_ERROR_INVALID_OPERATION;
138         }
139
140         send_len = muse_core_msg_send(send_fd, msg);
141         if (send_len <= 0) {
142                 LOGE("sending message failed");
143                 return PLAYER_ERROR_INVALID_OPERATION;
144         }
145
146         return PLAYER_ERROR_NONE;
147 }
148
149 static int _get_current_state(player_cli_s *pc, player_state_e *pstate)
150 {
151         PLAYER_INSTANCE_CHECK(pc);
152         PLAYER_NULL_ARG_CHECK(pstate);
153         muse_player_api_e api = MUSE_PLAYER_API_GET_STATE;
154         int ret = PLAYER_ERROR_NONE;
155         int state = PLAYER_STATE_NONE;
156         char *ret_buf = NULL;
157
158         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
159
160         if (ret == PLAYER_ERROR_NONE) {
161                 player_msg_get(state, ret_buf);
162                 *pstate = state;
163                 LOGD("current state %d", *pstate);
164         }
165
166         g_free(ret_buf);
167         return ret;
168 }
169
170 static bool _player_get_param_value(char *buf, ...)
171 {
172         muse_core_msg_parse_err_e err = MUSE_MSG_PARSE_ERROR_NONE;
173         bool ret = true;
174         va_list var_args;
175         int type = MUSE_TYPE_ANY;
176         char *param_name = NULL;
177         void *value = NULL;
178
179         LOGE("ENTER");
180
181         void *jobj = muse_core_msg_object_new(buf, NULL, &err);
182
183         if (!jobj) {
184                 LOGE("failed to get msg object. err:%d", err);
185                 return false;
186         }
187
188         va_start(var_args, buf);
189
190         while ((type = va_arg(var_args, int)) != INVALID_MUSE_TYPE_VALUE) {
191                 param_name = va_arg(var_args, char *);
192                 switch (type) {
193                 case MUSE_TYPE_INT:
194                 case MUSE_TYPE_INT64:
195                 case MUSE_TYPE_DOUBLE:
196                 case MUSE_TYPE_STRING:
197                 case MUSE_TYPE_POINTER:
198                         value = va_arg(var_args, void *);
199
200                         if (!muse_core_msg_object_get_value(param_name, jobj, type, value)) {
201                                 ret = false;
202                                 LOGE("failed to get %s value", param_name);
203                         }
204                         break;
205                 default:
206                         LOGE("Unexpected type");
207                         ret = false;
208                         break;
209                 }
210         }
211
212         muse_core_msg_object_free(jobj);
213
214         va_end(var_args);
215         return ret;
216 }
217
218 int _player_video_media_packet_finalize(media_packet_h pkt, int error_code, void *user_data)
219 {
220         int ret = MEDIA_PACKET_FINALIZE;
221         muse_player_api_e api = MUSE_PLAYER_API_RETURN_VIDEO_DATA;
222         _media_pkt_video_fin_data *fin_data = (_media_pkt_video_fin_data *)user_data;
223         intptr_t v_data = 0;
224         char *snd_msg = NULL;
225         int snd_len = 0;
226
227         if (!pkt) {
228                 LOGE("invalid parameter buffer %p, user_data %p", pkt, user_data);
229                 return ret;
230         }
231
232         if (!fin_data || fin_data->fd <= INVALID_DEFAULT_VALUE) {
233                 LOGE("invalid parameter, fd: %d", (fin_data) ? (fin_data->fd) : (-1));
234                 goto EXIT;
235         }
236
237         if (!fin_data->use_tsurf_pool) {
238                 tbm_surface_h tsurf = NULL;
239                 if (media_packet_get_tbm_surface(pkt, &tsurf) != MEDIA_PACKET_ERROR_NONE) {
240                         LOGE("media_packet_get_tbm_surface failed");
241                         /* continue the remained job */
242                 }
243                 if (tsurf) {
244                         /* LOGD("tsurf destroy %p", tsurf); */
245                         tbm_surface_destroy(tsurf);
246                         tsurf = NULL;
247                 }
248         } else {
249                 /* Do not destroy tbm surface here to reuse during playback          *
250                  * they will be destroyed at player_unprepare() or player_destroy(). *
251                  * ref: __player_remove_tsurf_list()                                 */
252
253                 tbm_surface_h tsurf = NULL;
254
255                 if (media_packet_get_tbm_surface(pkt, &tsurf) == MEDIA_PACKET_ERROR_NONE) {
256                         /* LOGD("tsurf set to null %p", tsurf); */
257                         tsurf = NULL;
258                 }
259         }
260
261         if (muse_core_fd_is_valid(fin_data->fd)) {
262                 if (muse_client_check_fd_id_value(fin_data->fd, fin_data->fd_id) == FALSE) {
263                         LOGE("[fd:%d,id:%d] is invalid.", fin_data->fd, fin_data->fd_id);
264                         goto EXIT;
265                 }
266
267                 v_data = fin_data->remote_v_data;
268                 snd_msg = muse_core_msg_new(api, MUSE_TYPE_POINTER, "v_data", v_data, 0);
269                 snd_len = muse_core_msg_send(fin_data->fd, snd_msg);
270                 muse_core_msg_free(snd_msg);
271
272                 if (snd_len <= 0)
273                         LOGE("[fd:%d] fail to send msg.", fin_data->fd);
274         } else {
275                 LOGE("[fd:%d] is invalid.", fin_data->fd);
276         }
277
278 EXIT:
279         if (fin_data) {
280                 g_free(fin_data);
281                 fin_data = NULL;
282         }
283
284         return ret;
285 }
286
287 int _player_audio_media_packet_finalize(media_packet_h pkt, int error_code, void *user_data)
288 {
289         int ret = MEDIA_PACKET_FINALIZE;
290         muse_player_api_e api = MUSE_PLAYER_API_RETURN_BUFFER;
291         _media_pkt_audio_fin_data *fin_data = (_media_pkt_audio_fin_data *)user_data;
292
293         if (!pkt) {
294                 LOGE("invalid parameter buffer %p, user_data %p", pkt, user_data);
295                 return ret;
296         }
297
298         if (!fin_data) {
299                 LOGE("invalid fin_data");
300                 goto EXIT;
301         }
302
303         if (fin_data->bo) {
304                 /* LOGD("release memory - %p", fin_data->bo); */
305                 tbm_bo_unref(fin_data->bo);
306         }
307
308         if (fin_data->fd > INVALID_DEFAULT_VALUE && muse_core_fd_is_valid(fin_data->fd)) {
309                 if (muse_client_check_fd_id_value(fin_data->fd, fin_data->fd_id) == FALSE) {
310                         LOGE("[fd:%d,id:%d] is invalid.", fin_data->fd, fin_data->fd_id);
311                         goto EXIT;
312                 }
313
314                 PLAYER_SEND_MSG_ASYNC_WITH_NO_RETURN(api, fin_data->fd, MUSE_TYPE_INT, "key", fin_data->key);
315         } else {
316                 LOGE("[fd:%d] is invalid.", fin_data->fd);
317         }
318
319 EXIT:
320         if (fin_data) {
321                 g_free(fin_data);
322                 fin_data = NULL;
323         }
324
325         return ret;
326 }
327
328 static bool _player_video_roi_area_is_valid(double x_scale, double y_scale,
329         double w_scale, double h_scale)
330 {
331         if (x_scale >= 0.0 && x_scale <= 1.0 && y_scale >= 0.0 && y_scale <= 1.0
332                         && w_scale > 0.0 && w_scale <= 1.0 && h_scale > 0.0 && h_scale <= 1.0)
333                 return true;
334
335         LOGE("Video roi area is not valid");
336         return false;
337 }
338
339 static bool _player_check_network_availability(void)
340 {
341 #define _FEATURE_NAME_WIFI              "http://tizen.org/feature/network.wifi"
342 #define _FEATURE_NAME_TELEPHONY "http://tizen.org/feature/network.telephony"
343 #define _FEATURE_NAME_ETHERNET  "http://tizen.org/feature/network.ethernet"
344         bool enabled = FALSE;
345         bool supported = FALSE;
346
347         if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_WIFI, &enabled)) {
348                 LOGI("wifi status = %d", enabled);
349                 if (enabled)
350                         supported = TRUE;
351         } else {
352                 LOGE("SYSTEM_INFO_ERROR");
353         }
354
355         if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_TELEPHONY, &enabled)) {
356                 LOGI("telephony status = %d", enabled);
357                 if (enabled)
358                         supported = TRUE;
359         } else {
360                 LOGE("SYSTEM_INFO_ERROR");
361         }
362
363         if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_bool(_FEATURE_NAME_ETHERNET, &enabled)) {
364                 LOGI("ethernet status = %d", enabled);
365                 if (enabled)
366                         supported = TRUE;
367         } else {
368                 LOGE("SYSTEM_INFO_ERROR");
369         }
370
371         if (!supported)
372                 return FALSE;
373
374         return TRUE;
375 }
376
377 static void *_get_mem(player_cli_s *player, int size)
378 {
379         player_data_s *mem = g_new(player_data_s, sizeof(player_data_s));
380         if (mem) {
381                 mem->data = g_new(void, size);
382                 mem->next = player->head;
383                 player->head = mem;
384                 return mem->data;
385         }
386         return NULL;
387 }
388
389 static void _del_mem(player_cli_s *player)
390 {
391         player_data_s *mem;
392         while (player->head) {
393                 mem = player->head->next;
394                 g_free(player->head->data);
395                 g_free(player->head);
396                 player->head = mem;
397         }
398 }
399
400 static int player_recv_msg(callback_cb_info_s *cb_info, tbm_fd *tfd)
401 {
402         int recvLen = 0;
403         msg_buff_s *buff = &cb_info->buff;
404
405         memset(buff->recvMsg, 0x00, sizeof(char) * buff->bufLen);
406         memset(tfd, INVALID_DEFAULT_VALUE, sizeof(*tfd) * MUSE_NUM_FD);
407         recvLen = muse_core_msg_recv_fd(cb_info->fd, buff->recvMsg, MUSE_MSG_MAX_LENGTH, tfd);
408         if (recvLen <= 0) {
409                 LOGE("failed to recv msg %d", recvLen);
410                 return 0;
411         }
412
413         /* check the first msg */
414         if (buff->part_of_msg && buff->recvMsg[0] != '{')
415         {
416                 gchar *tmp = g_strndup(buff->recvMsg, recvLen);
417                 if (!tmp) {
418                         LOGE("failed to copy msg.");
419                         return 0;
420                 }
421
422                 LOGD("get remained part of msg %d + %zu, %d", recvLen, strlen(buff->part_of_msg), buff->bufLen);
423
424                 /* realloc buffer */
425                 if (recvLen + strlen(buff->part_of_msg) >= buff->bufLen) {
426                         LOGD("realloc Buffer %d -> %d", buff->bufLen, (int)(recvLen + strlen(buff->part_of_msg) + 1));
427                         buff->bufLen = recvLen + strlen(buff->part_of_msg) + 1;
428                         buff->recvMsg = g_renew(char, buff->recvMsg, buff->bufLen);
429                         if (!buff->recvMsg) {
430                                 LOGE("failed renew buffer.");
431                                 g_free(tmp);
432                                 return 0;
433                         }
434                         memset(buff->recvMsg, 0x00, sizeof(char) * buff->bufLen);
435                 }
436                 g_snprintf(buff->recvMsg, buff->bufLen, "%s%s", buff->part_of_msg, tmp);
437                 recvLen += strlen(buff->part_of_msg);
438
439                 g_free(buff->part_of_msg);
440                 buff->part_of_msg = NULL;
441                 g_free(tmp);
442                 tmp = NULL;
443         }
444
445         /* check the last msg */
446         if (buff->recvMsg[recvLen - 1] != '}') {
447                 char *part_pos = strrchr(buff->recvMsg, '}');
448                 int part_len = ((part_pos) ? (strlen(part_pos + 1)) : (0));
449
450                 if (part_len > 0) {
451                         buff->part_of_msg = g_strndup(part_pos + 1, part_len);
452                         if (!buff->part_of_msg) {
453                                 LOGE("failed to alloc buffer for part of msg.");
454                                 return 0;
455                         }
456                         LOGD("get part of msg: %zu, %s", strlen(buff->part_of_msg), buff->part_of_msg);
457                         recvLen -= part_len;
458                 }
459         }
460
461         return recvLen;
462 }
463
464 static void set_null_user_cb(callback_cb_info_s *cb_info, muse_player_event_e event)
465 {
466         if (cb_info && event < MUSE_PLAYER_EVENT_TYPE_NUM) {
467                 cb_info->user_cb[event] = NULL;
468                 cb_info->user_data[event] = NULL;
469         }
470 }
471
472 /* Notice : have to be called via API to avoid deadlock
473  * to clear the cb setting at the cb thread, set_null_user_cb() have to be called instead.
474  */
475 static void set_null_user_cb_lock(callback_cb_info_s *cb_info, muse_player_event_e event)
476 {
477         bool lock = false;
478
479         LOGD("event %d cb will be cleared", event);
480
481         if (!cb_info) {
482                 LOGE("cb_info is NULL, event: %d", event);
483                 return;
484         }
485
486         lock = (g_thread_self() != cb_info->event_queue.thread);
487
488         if (lock)
489                 g_mutex_lock(&cb_info->event_queue.mutex);
490
491         if (_player_need_sync_context(event))
492                 _player_remove_idle_event(cb_info, event, false);
493
494         set_null_user_cb(cb_info, event);
495
496         if (lock)
497                 g_mutex_unlock(&cb_info->event_queue.mutex);
498 }
499
500 static int __set_callback(muse_player_event_e type, player_h player, void *callback, void *user_data)
501 {
502         int ret = PLAYER_ERROR_NONE;
503         player_cli_s *pc = (player_cli_s *)player;
504         muse_player_api_e api = MUSE_PLAYER_API_SET_CALLBACK;
505         char *ret_buf = NULL;
506         int set = 1;
507
508         PLAYER_INSTANCE_CHECK(player);
509         PLAYER_NULL_ARG_CHECK(callback);
510
511         if (type == MUSE_PLAYER_EVENT_TYPE_BUFFERING) {
512                 if (!_player_check_network_availability())
513                         return PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE;
514                 pc->cb_info->drop_buffering_message = FALSE;
515         }
516
517         if (!CALLBACK_INFO(pc))
518                 return PLAYER_ERROR_INVALID_OPERATION;
519
520         LOGI("Event type : %d ", type);
521         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
522                                         MUSE_TYPE_INT, "type", type,
523                                         MUSE_TYPE_INT, "set", set);
524
525         if (ret == PLAYER_ERROR_NONE) {
526                 pc->cb_info->user_cb[type] = callback;
527                 pc->cb_info->user_data[type] = user_data;
528         }
529
530         g_free(ret_buf);
531         return ret;
532 }
533
534 static int __unset_callback(muse_player_event_e type, player_h player)
535 {
536         int ret = PLAYER_ERROR_NONE;
537         player_cli_s *pc = (player_cli_s *)player;
538         muse_player_api_e api = MUSE_PLAYER_API_SET_CALLBACK;
539         char *ret_buf = NULL;
540         int set = 0;
541
542         PLAYER_INSTANCE_CHECK(player);
543
544         LOGI("Event type : %d ", type);
545
546         PLAYER_NULL_ARG_CHECK(CALLBACK_INFO(pc));
547
548         if ((type == MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME) ||
549                 (type == MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME)) {
550                 /* check state condition */
551                 player_state_e state = PLAYER_STATE_NONE;
552
553                 if (_get_current_state(pc, &state) != PLAYER_ERROR_NONE) {
554                         LOGE("Failed to get current state");
555                         return PLAYER_ERROR_INVALID_OPERATION;
556                 }
557
558                 if (state > PLAYER_STATE_READY) {
559                         LOGE("Invalid state %d", state);
560                         return PLAYER_ERROR_INVALID_STATE;
561                 }
562         }
563
564         set_null_user_cb_lock(CALLBACK_INFO(pc), type);
565
566         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
567                                         MUSE_TYPE_INT, "type", type,
568                                         MUSE_TYPE_INT, "set", set);
569
570         g_free(ret_buf);
571         return ret;
572 }
573
574 static void __prepare_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
575 {
576         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_PREPARE;
577
578         ((player_prepared_cb)cb_info->user_cb[ev])(cb_info->user_data[ev]);
579
580         set_null_user_cb(cb_info, ev);
581 }
582
583 static void __complete_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
584 {
585         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_COMPLETE;
586         ((player_completed_cb)cb_info->user_cb[ev])(cb_info->user_data[ev]);
587 }
588
589 static void __player_media_packet_video_decoded_cb(media_packet_h packet, void *user_data)
590 {
591         if (!packet || !user_data) {
592                 LOGE("invalid param [packet:%p, user_data:%p]", packet, user_data);
593                 return;
594         }
595
596         LOGD("render packet %p", packet);
597
598         mm_display_interface_evas_render(DP_INTERFACE((player_cli_s *)user_data), packet);
599 }
600
601 static void __retrieve_buffer_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
602
603 {
604         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_RETURN_BUFFER;
605         ((player_retrieve_buffer_cb)cb_info->user_cb[ev])(cb_info->user_data[ev]);
606 }
607
608 static void __interrupt_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
609 {
610         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_INTERRUPT;
611         ((player_interrupted_cb)cb_info->user_cb[ev])(PLAYER_INTERRUPTED_BY_RESOURCE_CONFLICT, cb_info->user_data[ev]);
612 }
613
614 static void __error_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
615 {
616         int code;
617         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_ERROR;
618
619         if (player_msg_get(code, recv_data->buffer)) {
620                 if (code == PLAYER_ERROR_NOT_SUPPORTED_FILE) {
621                         if (cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_PREPARE]) {
622                                 LOGW("failed to pause, so prepare cb will be released soon");
623                                 set_null_user_cb(cb_info, MUSE_PLAYER_EVENT_TYPE_PREPARE);
624                         }
625                 }
626                 ((player_error_cb)cb_info->user_cb[ev])(code, cb_info->user_data[ev]);
627         }
628 }
629
630 static void __disconnected_error_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
631 {
632         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_ERROR;
633
634         ((player_error_cb)cb_info->user_cb[ev])(PLAYER_ERROR_SERVICE_DISCONNECTED, cb_info->user_data[ev]);
635 }
636
637 static void __buffering_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
638 {
639         int percent;
640         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_BUFFERING;
641
642         if (player_msg_get(percent, recv_data->buffer)) {
643                 g_mutex_lock(&cb_info->buffering_cb_mutex);
644                 if (cb_info->drop_buffering_message) {
645                         LOGD("Drop buffering callback");
646                         g_mutex_unlock(&cb_info->buffering_cb_mutex);
647                         return;
648                 }
649                 g_mutex_unlock(&cb_info->buffering_cb_mutex);
650                 ((player_buffering_cb)cb_info->user_cb[ev])(percent, cb_info->user_data[ev]);
651         }
652
653 }
654
655 static void __subtitle_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
656 {
657         int duration = 0;
658         char text[MUSE_URI_MAX_LENGTH] = { 0, };
659         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_SUBTITLE;
660         bool ret = true;
661
662         ret = _player_get_param_value(recv_data->buffer,
663                                                                 MUSE_TYPE_INT, "duration", (void *)&duration,
664                                                                 MUSE_TYPE_STRING, "text", (void *)text,
665                                                                 INVALID_MUSE_TYPE_VALUE);
666         if (ret)
667                 ((player_subtitle_updated_cb)cb_info->user_cb[ev])(duration, text, cb_info->user_data[ev]);
668 }
669
670 static void __capture_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
671 {
672         unsigned char *data = NULL;
673         int width = 0;
674         int height = 0;
675         unsigned int size = 0;
676         tbm_bo bo = NULL;
677         tbm_bo_handle thandle;
678         int key = INVALID_DEFAULT_VALUE;
679         bool get_ret = true;
680         get_ret = _player_get_param_value(recv_data->buffer,
681                                                                         MUSE_TYPE_INT, "width", (void *)&width,
682                                                                         MUSE_TYPE_INT, "height", (void *)&height,
683                                                                         MUSE_TYPE_INT, "size", (void *)&size,
684                                                                         MUSE_TYPE_INT, "key", (void *)&key,
685                                                                         INVALID_MUSE_TYPE_VALUE);
686         if (get_ret) {
687                 if (recv_data->tfd[0] < 0) {
688                         LOGE("There is no valid tbm_fd");
689                         goto EXIT;
690                 }
691
692                 bo = tbm_bo_import_fd(cb_info->bufmgr, recv_data->tfd[0]);
693                 if (bo == NULL) {
694                         LOGE("TBM get error : bo is NULL");
695                         goto EXIT;
696                 }
697                 thandle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE | TBM_OPTION_READ);
698                 if (thandle.ptr == NULL) {
699                         LOGE("TBM get error : handle pointer is NULL");
700                         goto EXIT;
701                 }
702                 data = g_new(unsigned char, size);
703                 if (data) {
704                         memcpy(data, thandle.ptr, size);
705                         ((player_video_captured_cb)cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_CAPTURE])(data, width, height, size, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_CAPTURE]);
706                         g_free(data);
707                 } else {
708                         LOGE("g_new failure");
709                 }
710
711                 tbm_bo_unmap(bo);
712         }
713
714 EXIT:
715         PLAYER_CLOSE_FD(recv_data->tfd[0]);
716
717         memset(recv_data->tfd, INVALID_DEFAULT_VALUE, sizeof(recv_data->tfd));
718
719         if (bo)
720                 tbm_bo_unref(bo);
721
722         /* return buffer */
723         if (key > INVALID_DEFAULT_VALUE) {
724                 LOGD("send msg to release buffer. key:%d", key);
725                 PLAYER_SEND_MSG_ASYNC_WITH_NO_RETURN(MUSE_PLAYER_API_RETURN_BUFFER, cb_info->fd, MUSE_TYPE_INT, "key", key);
726         }
727
728         set_null_user_cb(cb_info, MUSE_PLAYER_EVENT_TYPE_CAPTURE);
729 }
730
731 static void __seek_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
732 {
733         int ret = MM_ERROR_NONE;
734         muse_player_event_e ev = MUSE_PLAYER_EVENT_TYPE_SEEK;
735         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
736
737         g_mutex_lock(&cb_info->seek_cb_mutex);
738
739         switch (cb_info->seek_cb_state) {
740         case PLAYER_SEEK_CB_STATE_NONE:
741         {
742                 if (!cb_info->user_cb[ev]) {
743                         LOGW("invalid seek callback info, skip");
744                         break;
745                 }
746
747                 ret = mm_display_interface_get_type(cb_info->dp_info.interface, &display_type);
748                 if (ret == MM_ERROR_NONE && display_type == MM_DISPLAY_TYPE_EVAS &&
749                         cb_info->dp_info.visible != PLAYER_VISIBLE_INFO_FALSE) {
750                         LOGW("set display visible true for EVAS");
751                         if (mm_display_interface_evas_set_visible(cb_info->dp_info.interface, true) != MM_ERROR_NONE)
752                                 LOGE("mm_display_interface_evas_set_visible failed");
753                 } else {
754                         LOGW("get display type ret 0x%x, type %d", ret, display_type);
755                 }
756
757                 LOGD("call seek cb");
758                 ((player_seek_completed_cb)cb_info->user_cb[ev])(cb_info->user_data[ev]);
759                 set_null_user_cb(cb_info, ev);
760
761                 break;
762         }
763         case PLAYER_SEEK_CB_STATE_DROP:
764         case PLAYER_SEEK_CB_STATE_WAIT: /* not expected */
765                 LOGW("ignored. seek cb %p, state %d", cb_info->user_cb[ev], cb_info->seek_cb_state);
766                 break;
767         default:
768                 LOGE("invalid state value");
769                 break;
770         }
771
772         g_mutex_unlock(&cb_info->seek_cb_mutex);
773 }
774
775 static void __player_remove_tsurf_list(player_cli_s *pc)
776 {
777         GList *l = NULL;
778
779         g_mutex_lock(&pc->cb_info->data_mutex);
780         if (pc->cb_info->tsurf_list) {
781                 LOGD("total num of tsurf list = %d", g_list_length(pc->cb_info->tsurf_list));
782
783                 for (l = g_list_first(pc->cb_info->tsurf_list); l; l = g_list_next(l)) {
784                         player_tsurf_info_s *tmp = (player_tsurf_info_s *)l->data;
785
786                         LOGD("%p will be removed", tmp);
787                         if (tmp) {
788                                 if (tmp->tsurf) {
789                                         tbm_surface_destroy(tmp->tsurf);
790                                         tmp->tsurf = NULL;
791                                 }
792                                 g_free(tmp);
793                         }
794                 }
795                 g_list_free(pc->cb_info->tsurf_list);
796                 pc->cb_info->tsurf_list = NULL;
797         }
798         g_mutex_unlock(&pc->cb_info->data_mutex);
799         return;
800 }
801
802 static player_tsurf_info_s *__player_get_tsurf_from_list(callback_cb_info_s *cb_info, intptr_t key, int height, int width)
803 {
804         GList *l = NULL;
805
806         g_mutex_lock(&cb_info->data_mutex);
807         for (l = g_list_first(cb_info->tsurf_list); l; l = g_list_next(l)) {
808                 player_tsurf_info_s *tmp = (player_tsurf_info_s *)l->data;
809                 if (tmp && key && (tmp->key == key)) {
810                         LOGD("found tsurf_data of tbm_key %" PRIdPTR, key);
811
812                         /* need to check tsuf info to support DRC */
813                         if ((tbm_surface_get_height(tmp->tsurf) != height) ||
814                                 (tbm_surface_get_width(tmp->tsurf) != width)) {
815
816                                 cb_info->tsurf_list = g_list_remove(cb_info->tsurf_list, tmp);
817                                 LOGW("tsurf info is changed. need to create new tsurf.");
818                                 tbm_surface_destroy(tmp->tsurf);
819                                 g_free(tmp);
820
821                                 g_mutex_unlock(&cb_info->data_mutex);
822                                 return NULL;
823
824                         } else {
825                                 g_mutex_unlock(&cb_info->data_mutex);
826                                 return tmp;
827                         }
828                 }
829         }
830         g_mutex_unlock(&cb_info->data_mutex);
831         return NULL;
832 }
833
834 static media_packet_rotate_method_e __convert_packet_orient_info(int orientation)
835 {
836         media_packet_rotate_method_e rotate = MEDIA_PACKET_ROTATE_IDENTITY;
837
838         switch (orientation) {
839         case 90:
840                 rotate = MEDIA_PACKET_ROTATE_90;
841         break;
842         case 180:
843                 rotate = MEDIA_PACKET_ROTATE_180;
844         break;
845         case 270:
846                 rotate = MEDIA_PACKET_ROTATE_270;
847         break;
848         default:
849                 rotate = MEDIA_PACKET_ROTATE_IDENTITY;
850         break;
851         }
852
853         return rotate;
854 }
855
856 static void __media_packet_video_frame_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
857 {
858         tbm_bo bo[4] = { NULL, };
859         tbm_surface_info_s sinfo;
860         char *surface_info = (char *)&sinfo;
861         media_packet_h pkt = NULL;
862         tbm_surface_h tsurf = NULL;
863         player_tsurf_info_s *tsurf_data = NULL;
864         int bo_num = 0;
865         media_format_mimetype_e mimetype = MEDIA_FORMAT_NV12;
866         bool make_pkt_fmt = false;
867         int ret = MEDIA_FORMAT_ERROR_NONE;
868         _media_pkt_video_fin_data *fin_data = NULL;
869         intptr_t key = 0;
870         intptr_t v_data = 0;
871         uint64_t pts = 0;
872         int i = 0, orientation = 0;
873         muse_core_msg_parse_err_e err = MUSE_MSG_PARSE_ERROR_NONE;
874
875         void *jobj = muse_core_msg_object_new(recv_data->buffer, NULL, &err);
876         if (!jobj ||
877                 !muse_core_msg_object_get_value("key", jobj, MUSE_TYPE_POINTER, &key) ||
878                 !muse_core_msg_object_get_value("v_data", jobj, MUSE_TYPE_POINTER, &v_data) ||
879                 !muse_core_msg_object_get_value("mimetype", jobj, MUSE_TYPE_ANY, &mimetype) ||
880                 !muse_core_msg_object_get_value("pts", jobj, MUSE_TYPE_INT64, &pts) ||
881                 !muse_core_msg_object_get_value("orientation", jobj, MUSE_TYPE_INT, &orientation) ||
882                 !muse_core_msg_object_get_value("surface_info", jobj, MUSE_TYPE_ARRAY, surface_info)) {
883
884                 LOGE("failed to get value from msg. jobj:%p, err:%d", jobj, err);
885                 if (jobj)
886                         muse_core_msg_object_free(jobj);
887                 goto ERROR;
888         }
889         muse_core_msg_object_free(jobj);
890
891         LOGD("width %d, height %d", sinfo.width, sinfo.height);
892
893         if (!cb_info) {
894                 LOGE("cb_info is null");
895                 goto ERROR;
896         }
897
898         if (!cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME]) {
899                 /* send msg to release v_data. */
900                 LOGE("_video_decoded_cb is not set");
901                 goto ERROR;
902         }
903
904         if (recv_data->tfd[0] <= INVALID_DEFAULT_VALUE) {
905                 LOGE("tbm fd is invalid");
906                 goto ERROR;
907         }
908
909         tsurf_data = __player_get_tsurf_from_list(cb_info, key, (int)sinfo.height, (int)sinfo.width);
910         if (!tsurf_data) {
911                 for (i = 0; i < MUSE_NUM_FD; i++) {
912                         if (recv_data->tfd[i] <= INVALID_DEFAULT_VALUE)
913                                 break;
914
915                         bo_num++;
916                         bo[i] = tbm_bo_import_fd(cb_info->bufmgr, recv_data->tfd[i]);
917                 }
918
919                 tsurf = tbm_surface_internal_create_with_bos(&sinfo, bo, bo_num);
920                 if (!tsurf) {
921                         LOGE("failed to create tbm surface");
922                         goto ERROR;
923                 }
924
925                 if (cb_info->use_tsurf_pool) {
926                         tsurf_data = g_try_new(player_tsurf_info_s, 1);
927                         if (!tsurf_data) {
928                                 LOGE("failed to alloc tsurf info");
929                                 goto ERROR;
930                         }
931                         tsurf_data->key = key;
932                         tsurf_data->tsurf = tsurf;
933
934                         g_mutex_lock(&cb_info->data_mutex);
935                         cb_info->tsurf_list = g_list_append(cb_info->tsurf_list, tsurf_data);
936                         LOGD("key %" PRIdPTR " is added to the pool", key);
937                         if (cb_info->video_frame_pool_size < g_list_length(cb_info->tsurf_list))
938                                 LOGE("need to check the pool size: %d < %d", cb_info->video_frame_pool_size, g_list_length(cb_info->tsurf_list));
939                         g_mutex_unlock(&cb_info->data_mutex);
940                 }
941         } else {
942                 if (tsurf_data->tsurf) {
943                         tsurf = tsurf_data->tsurf;
944                 } else {
945                         LOGE("tsurf_data->tsurf is null (never enter here)");
946                         goto ERROR;
947                 }
948         }
949
950         /* check media packet format */
951         if (cb_info->pkt_fmt) {
952                 int pkt_fmt_width = 0;
953                 int pkt_fmt_height = 0;
954                 media_format_mimetype_e pkt_fmt_mimetype = MEDIA_FORMAT_NV12;
955
956                 media_format_get_video_info(cb_info->pkt_fmt, &pkt_fmt_mimetype, &pkt_fmt_width, &pkt_fmt_height, NULL, NULL);
957                 if (pkt_fmt_mimetype != mimetype || pkt_fmt_width != sinfo.width || pkt_fmt_height != sinfo.height) {
958                         LOGW("different format. current 0x%x, %dx%d, new 0x%x, %dx%d", pkt_fmt_mimetype, pkt_fmt_width, pkt_fmt_height, mimetype, sinfo.width, sinfo.height);
959                         media_format_unref(cb_info->pkt_fmt);
960                         cb_info->pkt_fmt = NULL;
961                         make_pkt_fmt = true;
962                 }
963         } else {
964                 make_pkt_fmt = true;
965         }
966         /* create packet format */
967         if (make_pkt_fmt) {
968                 LOGI("make new pkt_fmt - mimetype 0x%x, %dx%d", mimetype, sinfo.width, sinfo.height);
969                 ret = media_format_create(&cb_info->pkt_fmt);
970                 if (ret == MEDIA_FORMAT_ERROR_NONE) {
971                         ret = media_format_set_video_mime(cb_info->pkt_fmt, mimetype);
972                         ret |= media_format_set_video_width(cb_info->pkt_fmt, sinfo.width);
973                         ret |= media_format_set_video_height(cb_info->pkt_fmt, sinfo.height);
974                         LOGI("media_format_set_video_mime,width,height ret : 0x%x", ret);
975                 } else {
976                         LOGE("media_format_create failed");
977                 }
978         }
979
980         fin_data = g_try_new0(_media_pkt_video_fin_data, 1);
981         if (!fin_data) {
982                 LOGE("failed to alloc fin_data");
983                 goto ERROR;
984         }
985         fin_data->remote_v_data = v_data;
986         fin_data->fd = cb_info->fd;
987         fin_data->use_tsurf_pool = cb_info->use_tsurf_pool;
988
989         /* Keep the fd id to check validation when the pkt is destroyed. */
990         fin_data->fd_id = muse_client_get_fd_id_value(fin_data->fd);
991
992         ret = media_packet_create_from_tbm_surface(cb_info->pkt_fmt, tsurf, (media_packet_finalize_cb)_player_video_media_packet_finalize, (void *)fin_data, &pkt);
993         if (ret != MEDIA_PACKET_ERROR_NONE || !pkt) {
994                 LOGE("media_packet_create_from_tbm_surface failed %d %p", ret, pkt);
995                 goto ERROR;
996         }
997
998         if (pts != 0) {
999                 ret = media_packet_set_pts(pkt, (uint64_t)pts);
1000                 if (ret != MEDIA_PACKET_ERROR_NONE)
1001                         LOGE("media_packet_set_pts failed");
1002         }
1003
1004         ret = media_packet_set_rotate_method(pkt, __convert_packet_orient_info(orientation));
1005         if (ret != MEDIA_PACKET_ERROR_NONE)
1006                 LOGE("media_packet_set_rotate_method failed");
1007
1008         if (cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME]) {
1009                 /* call media packet callback */
1010                 ((player_media_packet_video_decoded_cb)cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME])(pkt, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME]);
1011         } else {
1012                 LOGE("_video_decoded_cb is not set");
1013                 media_packet_destroy(pkt);
1014         }
1015
1016         /* if tsruf pool is enabled, bo_num can be zero. */
1017         for (i = 0; i < MUSE_NUM_FD; i++)
1018                 PLAYER_CLOSE_FD(recv_data->tfd[i]);
1019
1020         for (i = 0; i < bo_num; i++) {
1021                 if (bo[i])
1022                         tbm_bo_unref(bo[i]);
1023         }
1024
1025         memset(recv_data->tfd, INVALID_DEFAULT_VALUE, sizeof(recv_data->tfd));
1026         return;
1027
1028 ERROR:
1029         if (pkt)
1030                 media_packet_destroy(pkt);
1031         else if (!tsurf_data && tsurf)
1032                 tbm_surface_destroy(tsurf);
1033
1034         if (fin_data)
1035                 g_free(fin_data);
1036
1037         /* if tsruf pool is enabled, bo_num can be zero. */
1038         for (i = 0; i < MUSE_NUM_FD; i++)
1039                 PLAYER_CLOSE_FD(recv_data->tfd[i]);
1040
1041         for (i = 0; i < bo_num; i++) {
1042                 if (bo[i])
1043                         tbm_bo_unref(bo[i]);
1044         }
1045         memset(recv_data->tfd, INVALID_DEFAULT_VALUE, sizeof(recv_data->tfd));
1046
1047         if (cb_info && v_data)
1048                 PLAYER_SEND_MSG_ASYNC_WITH_NO_RETURN(MUSE_PLAYER_API_RETURN_VIDEO_DATA, cb_info->fd, MUSE_TYPE_POINTER, "v_data", v_data);
1049
1050         return;
1051 }
1052
1053 static void __media_packet_audio_frame_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1054 {
1055         int ret = MEDIA_FORMAT_ERROR_NONE;
1056         tbm_bo bo = NULL;
1057         tbm_bo_handle thandle;
1058         int key = INVALID_DEFAULT_VALUE;
1059         player_audio_decoded_data_info_t audio;
1060         media_packet_h pkt = NULL;
1061         media_format_h fmt = NULL;
1062         _media_pkt_audio_fin_data *fin_data = NULL;
1063
1064         if (!player_msg_get(key, recv_data->buffer)) {
1065                 LOGE("failed to get key value from msg.");
1066                 return;
1067         }
1068
1069         if (recv_data->tfd[0] < 0) {
1070                 LOGE("failed to get tbm_fd(key:%d)", key);
1071                 goto EXIT;
1072         }
1073
1074         bo = tbm_bo_import_fd(cb_info->bufmgr, recv_data->tfd[0]);
1075         if (bo == NULL) {
1076                 LOGE("TBM get error : bo is NULL, tbm_fd:%d(key:%d)", recv_data->tfd[0], key);
1077                 goto EXIT;
1078         }
1079
1080         thandle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE | TBM_OPTION_READ);
1081         if (thandle.ptr == NULL) {
1082                 LOGE("TBM get error : handle pointer is NULL");
1083                 goto EXIT;
1084         }
1085
1086         memcpy(&audio, thandle.ptr, sizeof(player_audio_decoded_data_info_t));
1087         audio.data = thandle.ptr + sizeof(player_audio_decoded_data_info_t);
1088         tbm_bo_unmap(bo);
1089
1090         /* LOGD("user callback data %p, size %d", audio.data, audio.size); */
1091         if (cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME]) {
1092                 ret = media_format_create(&fmt);
1093                 if (ret != MEDIA_FORMAT_ERROR_NONE || !fmt) {
1094                         LOGE("failed to create media format 0x%X %p", ret, fmt);
1095                         goto EXIT;
1096                 }
1097
1098                 ret = media_format_set_audio_mime(fmt, audio.pcm_format);
1099                 ret |= media_format_set_audio_samplerate(fmt, audio.rate);
1100                 ret |= media_format_set_audio_channel(fmt, audio.channel);
1101                 ret |= media_format_set_audio_channel_mask(fmt, audio.channel_mask);
1102                 if (ret != MEDIA_FORMAT_ERROR_NONE) {
1103                         LOGE("failed to set audio format 0x%X", ret);
1104                         goto EXIT;
1105                 }
1106
1107                 fin_data = g_new0(_media_pkt_audio_fin_data, 1);
1108                 if (!fin_data) {
1109                         LOGE("failed to alloc fin_data");
1110                         goto EXIT;
1111                 }
1112
1113                 fin_data->key = key;
1114                 fin_data->fd = cb_info->fd;
1115                 fin_data->bo = bo;
1116
1117                 /* Keep the fd id to check validation when the pkt is destroyed. */
1118                 fin_data->fd_id = muse_client_get_fd_id_value(fin_data->fd);
1119
1120                 ret = media_packet_create_from_external_memory(fmt, audio.data, audio.size,
1121                                 (media_packet_finalize_cb)_player_audio_media_packet_finalize, (void *)fin_data, &pkt);
1122                 if (ret != MEDIA_PACKET_ERROR_NONE || !pkt) {
1123                         LOGE("failed to create media packet 0x%X %p", ret, pkt);
1124                         if (pkt)
1125                                 media_packet_destroy(pkt); /* fin_data will be free in finalize function. */
1126                         else
1127                                 g_free(fin_data);
1128                         goto EXIT;
1129                 }
1130
1131                 media_format_unref(fmt);
1132                 fmt = NULL;
1133
1134                 ((player_media_packet_audio_decoded_cb)cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME])
1135                                         (pkt, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME]);
1136         } else {
1137                 LOGE("there is no registered cb");
1138                 goto EXIT;
1139         }
1140
1141 EXIT:
1142         PLAYER_CLOSE_FD(recv_data->tfd[0]);
1143
1144         memset(recv_data->tfd, INVALID_DEFAULT_VALUE, sizeof(recv_data->tfd));
1145
1146         if (fmt)
1147                 media_format_unref(fmt);
1148
1149         /* return buffer */
1150         if ((cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME] == NULL) &&
1151                 (key > INVALID_DEFAULT_VALUE)) {
1152
1153                 if (bo) tbm_bo_unref(bo);
1154
1155                 /* LOGD("send msg to release buffer. key:%d", key); */
1156                 PLAYER_SEND_MSG_ASYNC_WITH_NO_RETURN(MUSE_PLAYER_API_RETURN_BUFFER, cb_info->fd, MUSE_TYPE_INT, "key", key);
1157         }
1158
1159         return;
1160 }
1161
1162 static void __video_frame_render_error_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1163 {
1164 }
1165
1166 static void __supported_audio_effect_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1167 {
1168 }
1169
1170 static void __supported_audio_effect_preset_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1171 {
1172 }
1173
1174 static void __missed_plugin_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1175 {
1176 }
1177
1178 static void __media_stream_video_buffer_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1179 {
1180         /* player_media_stream_buffer_status_e status; */
1181         int status;
1182
1183         if (player_msg_get(status, recv_data->buffer)) {
1184                 ((player_media_stream_buffer_status_cb)
1185                         cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS])
1186                                 ((player_media_stream_buffer_status_e)status,
1187                                 cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS]);
1188         }
1189 }
1190
1191 static void __media_stream_audio_buffer_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1192 {
1193         /* player_media_stream_buffer_status_e status; */
1194         int status;
1195
1196         if (player_msg_get(status, recv_data->buffer)) {
1197                 ((player_media_stream_buffer_status_cb)
1198                         cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS])
1199                                 ((player_media_stream_buffer_status_e) status,
1200                                 cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS]);
1201         }
1202
1203 }
1204
1205 static void __media_stream_video_buffer_cb_handler_ex(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1206 {
1207         /* player_media_stream_buffer_status_e status; */
1208         int status;
1209         unsigned long long bytes;
1210         bool ret = true;
1211
1212         ret = _player_get_param_value(recv_data->buffer,
1213                                                                 MUSE_TYPE_INT, "status", (void *)&status,
1214                                                                 MUSE_TYPE_INT64, "bytes", (void *)&bytes,
1215                                                                 INVALID_MUSE_TYPE_VALUE);
1216         if (ret == true) {
1217                 ((player_media_stream_buffer_status_cb_ex)
1218                         cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS_WITH_INFO])
1219                         ((player_media_stream_buffer_status_e) status, bytes, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS_WITH_INFO]);
1220         }
1221 }
1222
1223 static void __media_stream_audio_buffer_cb_handler_ex(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1224 {
1225         /* player_media_stream_buffer_status_e status; */
1226         int status;
1227         unsigned long long bytes;
1228         bool ret = true;
1229
1230         ret = _player_get_param_value(recv_data->buffer,
1231                                                                 MUSE_TYPE_INT, "status", (void *)&status,
1232                                                                 MUSE_TYPE_INT64, "bytes", (void *)&bytes,
1233                                                                 INVALID_MUSE_TYPE_VALUE);
1234         if (ret == true) {
1235                 ((player_media_stream_buffer_status_cb_ex)
1236                         cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS_WITH_INFO])
1237                         ((player_media_stream_buffer_status_e) status, bytes, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS_WITH_INFO]);
1238         }
1239
1240 }
1241
1242 static void __media_stream_video_seek_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1243 {
1244         unsigned long long offset;
1245
1246         if (player_msg_get_type(offset, recv_data->buffer, INT64)) {
1247                 ((player_media_stream_seek_cb)
1248                         cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK])
1249                         (offset, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK]);
1250         }
1251 }
1252
1253 static void __media_stream_audio_seek_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1254 {
1255         unsigned long long offset;
1256
1257         if (player_msg_get_type(offset, recv_data->buffer, INT64)) {
1258                 ((player_media_stream_seek_cb)
1259                         cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK])
1260                         (offset, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK]);
1261         }
1262 }
1263
1264 static void __video_stream_changed_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data)
1265 {
1266         int width;
1267         int height;
1268         int fps;
1269         int bit_rate;
1270         bool ret_val = TRUE;
1271         ret_val = _player_get_param_value(recv_data->buffer,
1272                                                                         MUSE_TYPE_INT, "width", (void *)&width,
1273                                                                         MUSE_TYPE_INT, "height", (void *)&height,
1274                                                                         MUSE_TYPE_INT, "fps", (void *)&fps,
1275                                                                         MUSE_TYPE_INT, "bit_rate", (void *)&bit_rate,
1276                                                                         INVALID_MUSE_TYPE_VALUE);
1277         if (ret_val) {
1278                 ((player_video_stream_changed_cb)cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED])
1279                         (width, height, fps, bit_rate, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED]);
1280         }
1281 }
1282
1283 static void (*_user_callbacks[MUSE_PLAYER_EVENT_TYPE_NUM])(callback_cb_info_s *cb_info, _player_recv_data *recv_data) = {
1284         __prepare_cb_handler,   /* MUSE_PLAYER_EVENT_TYPE_PREPARE */
1285         __complete_cb_handler,  /* MUSE_PLAYER_EVENT_TYPE_COMPLETE */
1286         __interrupt_cb_handler, /* MUSE_PLAYER_EVENT_TYPE_INTERRUPT */
1287         __error_cb_handler,             /* MUSE_PLAYER_EVENT_TYPE_ERROR */
1288         __buffering_cb_handler, /* MUSE_PLAYER_EVENT_TYPE_BUFFERING */
1289         __subtitle_cb_handler,  /* MUSE_PLAYER_EVENT_TYPE_SUBTITLE */
1290         __capture_cb_handler,   /* MUSE_PLAYER_EVENT_TYPE_CAPTURE */
1291         __seek_cb_handler,              /* MUSE_PLAYER_EVENT_TYPE_SEEK */
1292         __media_packet_video_frame_cb_handler,  /* MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME */
1293         __media_packet_audio_frame_cb_handler,  /* MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME */
1294         __video_frame_render_error_cb_handler,  /* MUSE_PLAYER_EVENT_TYPE_VIDEO_FRAME_RENDER_ERROR */
1295         __supported_audio_effect_cb_handler,    /* MUSE_PLAYER_EVENT_TYPE_SUPPORTED_AUDIO_EFFECT */
1296         __supported_audio_effect_preset_cb_handler,     /* MUSE_PLAYER_EVENT_TYPE_SUPPORTED_AUDIO_EFFECT_PRESET */
1297         __missed_plugin_cb_handler,     /* MUSE_PLAYER_EVENT_TYPE_MISSED_PLUGIN */
1298 #ifdef _PLAYER_FOR_PRODUCT
1299         NULL,   /* MUSE_PLAYER_EVENT_TYPE_IMAGE_BUFFER */
1300         NULL,   /* MUSE_PLAYER_EVENT_TYPE_SELECTED_SUBTITLE_LANGUAGE */
1301 #endif
1302         __media_stream_video_buffer_cb_handler, /* MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS */
1303         __media_stream_audio_buffer_cb_handler, /* MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS */
1304         __media_stream_video_buffer_cb_handler_ex,      /* MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS_WITH_INFO */
1305         __media_stream_audio_buffer_cb_handler_ex,      /* MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS_WITH_INFO */
1306         __media_stream_video_seek_cb_handler,   /* MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK */
1307         __media_stream_audio_seek_cb_handler,   /* MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK */
1308         NULL,   /* MUSE_PLAYER_EVENT_TYPE_AUDIO_STREAM_CHANGED */
1309         __video_stream_changed_cb_handler,              /* MUSE_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED */
1310         __retrieve_buffer_cb_handler,           /* MUSE_PLAYER_EVENT_TYPE_RETURN_BUFFER */
1311         __disconnected_error_cb_handler,                /* MUSE_PLAYER_EVENT_TYPE_SERVICE_DISCONNECTED */
1312 };
1313
1314 gboolean _player_event_job_function(void *user_data)
1315 {
1316         _player_cb_data *data = (_player_cb_data *)user_data;
1317         muse_player_event_e ev;
1318
1319         if (!data || !data->cb_info) {
1320                 LOGE("invalid user data");
1321                 return FALSE;
1322         }
1323
1324         ev = data->int_data;
1325         if ((ev != MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME) &&
1326                 (ev != MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME))
1327                 LOGD("enter ev:%d(%p)", ev, data);
1328
1329         /* remove event from list */
1330         g_mutex_lock(&data->cb_info->event_queue.idle_ev_mutex);
1331         if (data->cb_info->event_queue.idle_ev_list) {
1332                 /* LOGD("remove idle event %p, %p", data, data->cb_info->event_queue.idle_ev_list); */
1333                 data->cb_info->event_queue.idle_ev_list = g_list_remove(data->cb_info->event_queue.idle_ev_list, (gpointer)data);
1334         }
1335         g_mutex_unlock(&data->cb_info->event_queue.idle_ev_mutex);
1336
1337         if ((data->cb_info->user_cb[ev] || ev == MUSE_PLAYER_EVENT_TYPE_SERVICE_DISCONNECTED) &&
1338                 (_user_callbacks[ev]))
1339                 _user_callbacks[ev](data->cb_info, data->recv_data);
1340         else
1341                 LOGW("user callback is unset. type : %d", ev);
1342
1343         return FALSE; /* remove from the event list */
1344 }
1345
1346 static bool _player_need_sync_context(int event_id)
1347 {
1348         if ((event_id == MUSE_PLAYER_EVENT_TYPE_INTERRUPT) ||
1349                 (event_id == MUSE_PLAYER_EVENT_TYPE_BUFFERING) ||
1350                 (event_id == MUSE_PLAYER_EVENT_TYPE_COMPLETE) ||
1351                 (event_id == MUSE_PLAYER_EVENT_TYPE_ERROR) ||
1352                 (event_id == MUSE_PLAYER_EVENT_TYPE_SERVICE_DISCONNECTED) ||
1353                 (event_id == MUSE_PLAYER_EVENT_TYPE_PREPARE)) {
1354                 LOGD("%d callback will be issued in the mainloop.", event_id);
1355                 return TRUE;
1356         } else {
1357                 return FALSE;
1358         }
1359 }
1360
1361 static void _destroy_event_data(gpointer user_data)
1362 {
1363         _player_cb_data *data = (_player_cb_data *)user_data;
1364
1365         if (data == NULL) {
1366                 LOGW("data is null");
1367                 return;
1368         }
1369
1370         LOGD("remove event data %p (%d)", data, data->int_data);
1371         if (data->recv_data) {
1372                 g_free(data->recv_data->buffer);
1373                 data->recv_data->buffer = NULL;
1374                 g_free(data->recv_data);
1375                 data->recv_data = NULL;
1376         }
1377
1378         g_free(data);
1379 }
1380
1381 static void *_player_event_queue_loop(void *param)
1382 {
1383         if (!param) {
1384                 LOGE("NULL parameter");
1385                 return NULL;
1386         }
1387         callback_cb_info_s *cb_info = param;
1388         player_event_queue *ev = &cb_info->event_queue;
1389         _player_cb_data *event_data = NULL;
1390
1391         g_mutex_lock(&ev->mutex);
1392         while (ev->running) {
1393                 g_mutex_lock(&ev->qlock);
1394                 if (g_queue_is_empty(ev->queue)) {
1395                         g_mutex_unlock(&ev->qlock);
1396                         g_cond_wait(&ev->cond, &ev->mutex);
1397                         if (!ev->running)
1398                                 break;
1399                 } else
1400                         g_mutex_unlock(&ev->qlock);
1401
1402                 while (1) {
1403                         g_mutex_lock(&ev->qlock);
1404                         event_data = (_player_cb_data *)g_queue_pop_head(ev->queue);
1405                         g_mutex_unlock(&ev->qlock);
1406
1407                         if (!event_data)
1408                                 break;
1409
1410                         muse_player_event_e event_type = event_data->int_data;
1411
1412                         if (event_type == MUSE_PLAYER_EVENT_TYPE_SEEK) {
1413                                 g_mutex_lock(&cb_info->seek_cb_mutex);
1414                                 if (cb_info->seek_cb_state == PLAYER_SEEK_CB_STATE_WAIT) {
1415                                         /* push event into queue again. */
1416                                         _player_event_queue_add(ev, event_data);
1417                                         g_mutex_unlock(&cb_info->seek_cb_mutex);
1418                                         break;
1419                                 }
1420                                 g_mutex_unlock(&cb_info->seek_cb_mutex);
1421                         } else if (event_type == MUSE_PLAYER_EVENT_TYPE_BUFFERING) {
1422                                 g_mutex_lock(&cb_info->buffering_cb_mutex);
1423                                 if (cb_info->drop_buffering_message) {
1424                                         LOGD("Drop buffering event");
1425                                         g_mutex_unlock(&cb_info->buffering_cb_mutex);
1426
1427                                         _destroy_event_data(event_data);
1428                                         break;
1429                                 }
1430                                 g_mutex_unlock(&cb_info->buffering_cb_mutex);
1431                         }
1432
1433                         if (_player_need_sync_context(event_type)) {
1434                                 if ((cb_info->user_cb[event_type] || (event_type == MUSE_PLAYER_EVENT_TYPE_SERVICE_DISCONNECTED)) &&
1435                                         _user_callbacks[event_type]) {
1436                                         g_mutex_lock(&ev->idle_ev_mutex);
1437                                         ev->idle_ev_list = g_list_append(ev->idle_ev_list, (gpointer)event_data);
1438                                         g_mutex_unlock(&ev->idle_ev_mutex);
1439
1440                                         LOGD("add ev %d to main loop", event_type);
1441
1442                                         g_idle_add_full(G_PRIORITY_DEFAULT,
1443                                                                         (GSourceFunc)_player_event_job_function,
1444                                                                         (gpointer)event_data,
1445                                                                         (GDestroyNotify)_destroy_event_data);
1446                                 } else {
1447                                         LOGW("there is no registered cb for ev:%d", event_type);
1448                                         _destroy_event_data(event_data);
1449                                 }
1450                         } else {
1451                                 _player_event_job_function(event_data);
1452                                 _destroy_event_data(event_data);
1453                         }
1454                 }
1455         }
1456         g_mutex_unlock(&ev->mutex);
1457         LOGI("Exit event loop");
1458         return NULL;
1459 }
1460
1461 static gboolean _player_event_queue_new(callback_cb_info_s *cb_info)
1462 {
1463         g_return_val_if_fail(cb_info, FALSE);
1464         player_event_queue *ev = &cb_info->event_queue;
1465
1466         ev->queue = g_queue_new();
1467         g_return_val_if_fail(ev->queue, FALSE);
1468         g_mutex_init(&ev->qlock);
1469
1470         g_mutex_init(&ev->mutex);
1471         g_cond_init(&ev->cond);
1472         ev->running = TRUE;
1473
1474         g_mutex_init(&ev->idle_ev_mutex);
1475
1476         ev->thread = g_thread_new("cb_event_thread", _player_event_queue_loop, (gpointer)cb_info);
1477         g_return_val_if_fail(ev->thread, FALSE);
1478         LOGI("event queue thread %p", ev->thread);
1479
1480         return TRUE;
1481
1482 }
1483
1484 static void _player_remove_idle_event(callback_cb_info_s *cb_info, muse_player_event_e event_type, bool remove_all)
1485 {
1486         g_return_if_fail(cb_info);
1487         player_event_queue *ev = &cb_info->event_queue;
1488         _player_cb_data *event_data = NULL;
1489         GList *list = NULL;
1490
1491         g_mutex_lock(&ev->idle_ev_mutex);
1492
1493         if (ev->idle_ev_list == NULL) {
1494                 LOGD("No idle event is remained.");
1495                 g_mutex_unlock(&ev->idle_ev_mutex);
1496                 return;
1497         }
1498
1499         LOGD("remove idle event[%d] or all[%d]", event_type, remove_all);
1500
1501         list = ev->idle_ev_list;
1502         while (list) {
1503                 event_data = list->data;
1504                 list = g_list_next(list);
1505
1506                 if (!event_data) {
1507                         LOGW("Fail to remove idle event. The data is NULL");
1508                         continue;
1509                 }
1510
1511                 if ((event_data->int_data != event_type) && !remove_all)
1512                         continue;
1513
1514                 LOGD("remove idle event [%p:%d]", event_data, event_data->int_data);
1515
1516                 /* set cb to null */
1517                 if (remove_all)
1518                         set_null_user_cb(cb_info, event_data->int_data);
1519
1520                 ev->idle_ev_list = g_list_remove(ev->idle_ev_list, (gpointer)event_data);
1521
1522                 if (!g_idle_remove_by_data(event_data))
1523                         LOGW("failed to find source with %p", event_data);
1524         }
1525
1526         if (remove_all) {
1527                 g_list_free(ev->idle_ev_list);
1528                 ev->idle_ev_list = NULL;
1529         }
1530
1531         g_mutex_unlock(&ev->idle_ev_mutex);
1532
1533         LOGD("LEAVE");
1534         return;
1535 }
1536
1537 static void _player_event_queue_destroy(callback_cb_info_s *cb_info)
1538 {
1539         g_return_if_fail(cb_info);
1540         player_event_queue *ev = &cb_info->event_queue;
1541         _player_cb_data *event_data;
1542
1543         LOGI("event queue thread %p", ev->thread);
1544
1545         g_mutex_lock(&ev->mutex);
1546         ev->running = FALSE;
1547         g_cond_broadcast(&ev->cond);
1548         g_mutex_unlock(&ev->mutex);
1549
1550         g_thread_join(ev->thread);
1551         ev->thread = NULL;
1552
1553         while (!g_queue_is_empty(ev->queue)) {
1554                 event_data = (_player_cb_data *)g_queue_pop_head(ev->queue);
1555                 if (event_data) {
1556                         g_free(event_data->recv_data->buffer);
1557                         g_free(event_data->recv_data);
1558                         g_free(event_data);
1559                 }
1560         }
1561         g_queue_free(ev->queue);
1562         g_mutex_clear(&ev->qlock);
1563         g_mutex_clear(&ev->mutex);
1564         g_cond_clear(&ev->cond);
1565         g_mutex_clear(&ev->idle_ev_mutex);
1566 }
1567
1568 static void _player_event_queue_remove(player_event_queue *ev_queue, int ev)
1569 {
1570         GList *item;
1571
1572         g_mutex_lock(&ev_queue->qlock);
1573
1574         item = g_queue_peek_head_link(ev_queue->queue);
1575         while (item) {
1576                 GList *next = item->next;
1577                 _player_cb_data *cb_data = (_player_cb_data *)item->data;
1578
1579                 if (cb_data && cb_data->int_data == ev) {
1580                         LOGD("removing '%p (ev:%d)' from event queue", cb_data, cb_data->int_data);
1581                         g_free(cb_data->recv_data->buffer);
1582                         g_free(cb_data->recv_data);
1583                         g_free(cb_data);
1584
1585                         g_queue_delete_link(ev_queue->queue, item);
1586                 }
1587                 item = next;
1588         }
1589         g_mutex_unlock(&ev_queue->qlock);
1590 }
1591
1592 static void _player_event_queue_add(player_event_queue *ev, _player_cb_data *data)
1593 {
1594         if (ev->running) {
1595                 g_mutex_lock(&ev->qlock);
1596                 g_queue_push_tail(ev->queue, (gpointer)data);
1597                 g_mutex_unlock(&ev->qlock);
1598                 g_cond_signal(&ev->cond);
1599         }
1600 }
1601
1602 static bool _user_callback_handler(callback_cb_info_s *cb_info, muse_player_event_e event, _player_recv_data *recv_data)
1603 {
1604         /* LOGD("get event %d", event); */
1605
1606         if (event < MUSE_PLAYER_EVENT_TYPE_NUM) {
1607                 if (cb_info->user_cb[event] && _user_callbacks[event]) {
1608                         _player_cb_data *data = NULL;
1609                         data = g_new(_player_cb_data, 1);
1610                         if (!data) {
1611                                 LOGE("fail to alloc mem");
1612                                 return false;
1613                         }
1614                         data->int_data = (int)event;
1615                         data->cb_info = cb_info;
1616                         data->recv_data = recv_data;
1617                         _player_event_queue_add(&cb_info->event_queue, data);
1618
1619                         return true;
1620                 }
1621         }
1622
1623         LOGE("failed to add event to queue %d", event);
1624         return false;
1625 }
1626
1627 static void _add_ret_msg(muse_player_api_e api, callback_cb_info_s *cb_info, int offset, int parse_len)
1628 {
1629         ret_msg_s *msg = NULL;
1630         ret_msg_s *last = cb_info->buff.retMsgHead;
1631
1632         msg = g_new(ret_msg_s, 1);
1633         if (msg) {
1634                 msg->api = api;
1635                 msg->msg = g_strndup(cb_info->buff.recvMsg + offset, parse_len);
1636                 msg->next = NULL;
1637                 if (last == NULL)
1638                         cb_info->buff.retMsgHead = msg;
1639                 else {
1640                         while (last->next)
1641                                 last = last->next;
1642                         last->next = msg;
1643                 }
1644         } else
1645                 LOGE("g_new failure");
1646 }
1647
1648 static ret_msg_s *_get_ret_msg(muse_player_api_e api, callback_cb_info_s *cb_info)
1649 {
1650         ret_msg_s *msg = cb_info->buff.retMsgHead;
1651         ret_msg_s *prev = NULL;
1652         while (msg) {
1653                 if (msg->api == api) {
1654                         if (!prev)
1655                                 cb_info->buff.retMsgHead = msg->next;
1656                         else
1657                                 prev->next = msg->next;
1658                         return msg;
1659                 }
1660                 prev = msg;
1661                 msg = msg->next;
1662         }
1663         return NULL;
1664 }
1665
1666 static void _remove_all_ret_msg(callback_cb_info_s *cb_info)
1667 {
1668         ret_msg_s *msg = cb_info->buff.retMsgHead;
1669         ret_msg_s *prev = NULL;
1670         while (msg) {
1671                 prev = msg;
1672                 msg = msg->next;
1673                 LOGI("Remove %s", prev->msg);
1674                 g_free(prev->msg);
1675                 prev->msg = NULL;
1676                 g_free(prev);
1677         }
1678 }
1679
1680 static void _notify_disconnected(callback_cb_info_s *cb_info)
1681 {
1682         muse_player_event_e event = MUSE_PLAYER_EVENT_TYPE_SERVICE_DISCONNECTED;
1683         if (!cb_info || !cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_ERROR])
1684                 return;
1685
1686         if (_user_callbacks[event]) {
1687                 _player_cb_data *data = NULL;
1688                 data = g_new(_player_cb_data, 1);
1689                 if (!data) {
1690                         LOGE("fail to alloc mem");
1691                         return;
1692                 }
1693                 data->int_data = (int)event;
1694                 data->cb_info = cb_info;
1695                 data->recv_data = NULL;
1696                 _player_event_queue_add(&cb_info->event_queue, data);
1697         }
1698 }
1699
1700 static void *client_cb_handler(gpointer data)
1701 {
1702         int api;
1703         int len = 0;
1704         int parse_len = 0;
1705         int offset = 0;
1706         callback_cb_info_s *cb_info = data;
1707         char *recvMsg = NULL;
1708         muse_core_msg_parse_err_e err;
1709         tbm_fd tfd[MUSE_NUM_FD];
1710
1711         while (g_atomic_int_get(&cb_info->running)) {
1712                 len = 0;
1713                 err = MUSE_MSG_PARSE_ERROR_NONE;
1714
1715                 len = player_recv_msg(cb_info, tfd);
1716                 if (len <= 0)
1717                         break;
1718
1719                 recvMsg = cb_info->buff.recvMsg;
1720                 recvMsg[len] = '\0';
1721
1722                 parse_len = len;
1723                 offset = 0;
1724                 while (offset < len) {
1725                         api = MUSE_PLAYER_API_MAX;
1726 //                      LOGD(">>>>>> [%d/%d] %p, %s", offset, len, recvMsg + offset, recvMsg + offset);
1727 //                      usleep(10 * 1000);
1728
1729                         void *jobj = muse_core_msg_object_new(recvMsg + offset, &parse_len, &err);
1730                         if (jobj) {
1731                                 if (muse_core_msg_object_get_value("api", jobj, MUSE_TYPE_INT, &api)) {
1732                                         if (api < MUSE_PLAYER_API_MAX) {
1733                                                 g_mutex_lock(&cb_info->player_mutex);
1734                                                 cb_info->buff.recved++;
1735                                                 _add_ret_msg(api, cb_info, offset, parse_len);
1736                                                 if (api == MUSE_PLAYER_API_GET_ALBUM_ART && tfd[0] != INVALID_DEFAULT_VALUE) {
1737                                                         LOGD("get tbm fd for album art.");
1738                                                         cb_info->tfd = tfd[0];
1739                                                 }
1740                                                 g_cond_signal(&cb_info->player_cond[api]);
1741                                                 g_mutex_unlock(&cb_info->player_mutex);
1742                                                 if (api == MUSE_PLAYER_API_DESTROY)
1743                                                         g_atomic_int_set(&cb_info->running, 0);
1744                                         } else if (api == MUSE_PLAYER_CB_EVENT) {
1745                                                 int event;
1746                                                 _player_recv_data *recv_data = NULL;
1747                                                 g_mutex_lock(&cb_info->player_mutex);
1748                                                 recv_data = g_new0(_player_recv_data, 1);
1749                                                 if (recv_data != NULL) {
1750                                                         memcpy(recv_data->tfd, tfd, sizeof(recv_data->tfd));
1751                                                         recv_data->buffer = g_strndup(recvMsg + offset, parse_len);
1752                                                 } else {
1753                                                         LOGE("failed to alloc recv_data.");
1754                                                         g_mutex_unlock(&cb_info->player_mutex);
1755                                                         muse_core_msg_object_free(jobj);
1756                                                         break;
1757                                                 }
1758                                                 g_mutex_unlock(&cb_info->player_mutex);
1759                                                 if (!muse_core_msg_object_get_value("event", jobj, MUSE_TYPE_INT, &event) ||
1760                                                         !_user_callback_handler(cb_info, event, recv_data)) {
1761                                                         LOGE("failed to get value or add event to the queue.");
1762                                                         if (recv_data) {
1763                                                                 g_free(recv_data->buffer);
1764                                                                 g_free(recv_data);
1765                                                         }
1766                                                 }
1767                                         } else if (api == MUSE_PLAYER_CB_CREATE_ACK) {
1768                                                 g_mutex_lock(&cb_info->player_mutex);
1769                                                 cb_info->buff.recved++;
1770                                                 g_cond_signal(&cb_info->server_ack_cond);
1771                                                 g_mutex_unlock(&cb_info->player_mutex);
1772                                         }
1773                                 } else {
1774                                         LOGE("Failed to get value. offset:%d/%d, [msg][ %s ]", offset, len, (recvMsg + offset));
1775                                 }
1776                                 muse_core_msg_object_free(jobj);
1777                         } else {
1778                                 LOGE("Failed to get msg obj. err:%d", err);
1779                         }
1780
1781                         if (parse_len == 0 || err != MUSE_MSG_PARSE_ERROR_NONE)
1782                                 break;
1783
1784                         offset += parse_len;
1785                         parse_len = len - offset;
1786                 }
1787         }
1788         if (g_atomic_int_get(&cb_info->running))
1789                 _notify_disconnected(cb_info);
1790
1791         g_atomic_int_set(&cb_info->running, 0);
1792         LOGD("client cb exit");
1793
1794         return NULL;
1795 }
1796
1797 static callback_cb_info_s *callback_new(gint sockfd)
1798 {
1799         callback_cb_info_s *cb_info;
1800         msg_buff_s *buff;
1801         int i;
1802
1803         g_return_val_if_fail(sockfd > 0, NULL);
1804
1805         cb_info = g_new(callback_cb_info_s, 1);
1806         if (!cb_info)
1807                 return NULL;
1808         memset(cb_info, 0, sizeof(callback_cb_info_s));
1809
1810         g_mutex_init(&cb_info->player_mutex);
1811         for (i = 0; i < MUSE_PLAYER_API_MAX; i++)
1812                 g_cond_init(&cb_info->player_cond[i]);
1813         g_cond_init(&cb_info->server_ack_cond);
1814
1815         g_mutex_init(&cb_info->data_mutex);
1816         g_mutex_init(&cb_info->seek_cb_mutex);
1817         g_mutex_init(&cb_info->buffering_cb_mutex);
1818         cb_info->drop_buffering_message = FALSE;
1819
1820         buff = &cb_info->buff;
1821         buff->recvMsg = g_new(char, MUSE_MSG_MAX_LENGTH + 1);
1822         buff->bufLen = MUSE_MSG_MAX_LENGTH + 1;
1823         buff->recved = 0;
1824         buff->retMsgHead = NULL;
1825         buff->part_of_msg = NULL;
1826
1827         g_atomic_int_set(&cb_info->running, 1);
1828         cb_info->fd = sockfd;
1829         cb_info->tfd = INVALID_DEFAULT_VALUE;
1830         cb_info->data_fd = INVALID_DEFAULT_VALUE;
1831         cb_info->thread = g_thread_new("callback_thread", client_cb_handler, (gpointer) cb_info);
1832
1833         return cb_info;
1834 }
1835
1836 static void callback_destroy(callback_cb_info_s *cb_info)
1837 {
1838         int i;
1839         g_return_if_fail(cb_info);
1840
1841         if (cb_info->fd > INVALID_DEFAULT_VALUE)
1842                 muse_client_close(cb_info->fd);
1843         if (cb_info->data_fd > INVALID_DEFAULT_VALUE)
1844                 muse_client_close(cb_info->data_fd);
1845
1846         cb_info->fd = cb_info->data_fd = INVALID_DEFAULT_VALUE;
1847
1848         g_thread_join(cb_info->thread);
1849         cb_info->thread = NULL;
1850
1851         LOGI("%p Callback destroyed", cb_info);
1852
1853         for (i = 0; i < MUSE_PLAYER_API_MAX; i++) {
1854                 g_mutex_lock(&cb_info->player_mutex);
1855                 g_cond_signal(&cb_info->player_cond[i]);
1856                 g_mutex_unlock(&cb_info->player_mutex);
1857                 g_cond_clear(&cb_info->player_cond[i]);
1858         }
1859
1860         /* to make sure the return of other pending api */
1861         sched_yield();
1862         g_mutex_lock(&cb_info->player_mutex);
1863         g_mutex_unlock(&cb_info->player_mutex);
1864         g_mutex_clear(&cb_info->player_mutex);
1865
1866         g_cond_clear(&cb_info->server_ack_cond);
1867
1868         g_mutex_clear(&cb_info->data_mutex);
1869         g_mutex_clear(&cb_info->seek_cb_mutex);
1870         g_mutex_clear(&cb_info->buffering_cb_mutex);
1871
1872         g_free(cb_info->buff.recvMsg);
1873         _remove_all_ret_msg(cb_info);
1874         g_free(cb_info->buff.part_of_msg);
1875
1876         g_free(cb_info);
1877 }
1878
1879 int client_get_api_timeout(player_cli_s *pc, muse_player_api_e api)
1880 {
1881         int timeout = 0;
1882
1883         switch (api) {
1884         case MUSE_PLAYER_API_PREPARE:
1885         case MUSE_PLAYER_API_PREPARE_ASYNC:
1886         case MUSE_PLAYER_API_UNPREPARE:
1887         case MUSE_PLAYER_API_START:
1888         case MUSE_PLAYER_API_STOP:
1889         case MUSE_PLAYER_API_PAUSE:
1890                 timeout += SERVER_TIMEOUT(pc);
1891                 break;
1892         default:
1893                 /* check prepare async is done */
1894                 if (pc && CALLBACK_INFO(pc) && CALLBACK_INFO(pc)->user_cb[MUSE_PLAYER_EVENT_TYPE_PREPARE])
1895                         timeout += SERVER_TIMEOUT(pc);
1896                 break;
1897         }
1898         timeout += CALLBACK_TIME_OUT;
1899         return timeout; /* ms */
1900 }
1901
1902 int client_wait_for_cb_return(muse_player_api_e api, callback_cb_info_s *cb_info, char **ret_buf, int time_out)
1903 {
1904         int ret = PLAYER_ERROR_NONE;
1905         gint64 end_time = g_get_monotonic_time() + time_out * G_TIME_SPAN_MILLISECOND;
1906         msg_buff_s *buff = &cb_info->buff;
1907         ret_msg_s *msg = NULL;
1908
1909         g_mutex_lock(&cb_info->player_mutex);
1910
1911         msg = _get_ret_msg(api, cb_info);
1912         do {
1913                 if (!buff->recved || !msg) {
1914                         if (!g_cond_wait_until(&cb_info->player_cond[api], &cb_info->player_mutex, end_time)) {
1915                                 LOGW("api %d return msg does not received %dms", api, time_out);
1916                                 ret = PLAYER_ERROR_INVALID_OPERATION;
1917                                 break;
1918                         }
1919                 }
1920
1921                 if (!msg)
1922                         msg = _get_ret_msg(api, cb_info);
1923                 if (msg) {
1924                         *ret_buf = msg->msg;
1925                         buff->recved--;
1926                         g_free(msg);
1927                         if (!player_msg_get(ret, *ret_buf))
1928                                 ret = PLAYER_ERROR_INVALID_OPERATION;
1929                         else if (ret != PLAYER_ERROR_NONE)
1930                                 LOGE("Get error return from server 0x%X", ret);
1931                         break;
1932                 }
1933
1934                 if (!g_atomic_int_get(&cb_info->running)) {
1935                         LOGE("callback thread is stopped. %d api did not get return in time", api);
1936                         ret = PLAYER_ERROR_INVALID_OPERATION;
1937                         break;
1938                 } else {
1939                         LOGW("api %d is the spurious wakeup, wait again", api);
1940                 }
1941         } while (!msg && g_atomic_int_get(&cb_info->running));
1942
1943         g_mutex_unlock(&cb_info->player_mutex);
1944         return ret;
1945 }
1946
1947 int client_wait_for_server_ack(muse_player_api_e api, callback_cb_info_s *cb_info, int time_out)
1948 {
1949         int ret = PLAYER_ERROR_NONE;
1950         gint64 end_time = g_get_monotonic_time() + time_out * G_TIME_SPAN_MILLISECOND;
1951         msg_buff_s *buff = &cb_info->buff;
1952
1953         g_mutex_lock(&cb_info->player_mutex);
1954
1955         if (!buff->recved) {
1956                 if (!g_cond_wait_until(&cb_info->server_ack_cond, &cb_info->player_mutex, end_time)) {
1957                         LOGW("server ack msg does not received %dms", time_out);
1958                         if (!buff->recved)
1959                                 ret =  PLAYER_ERROR_INVALID_OPERATION;
1960                         else
1961                                 LOGD("Another msg is received, continue create handle");
1962                         g_mutex_unlock(&cb_info->player_mutex);
1963                         return ret;
1964                 }
1965         }
1966         buff->recved--;
1967
1968         g_mutex_unlock(&cb_info->player_mutex);
1969
1970         return ret;
1971 }
1972
1973
1974 /*
1975 * Public Implementation
1976 */
1977
1978 int player_create(player_h *player)
1979 {
1980         int ret = PLAYER_ERROR_NONE;
1981         int sock_fd = INVALID_DEFAULT_VALUE;
1982         int pid = getpid();
1983
1984         muse_player_api_e api = MUSE_PLAYER_API_CREATE;
1985         int module_index = INVALID_DEFAULT_VALUE;
1986         player_cli_s *pc = NULL;
1987         gchar *ret_buf = NULL;
1988         int retry_count = CONNECTION_RETRY;
1989
1990         PLAYER_INSTANCE_CHECK(player);
1991
1992         LOGD("ENTER");
1993
1994         pc = g_new0(player_cli_s, 1);
1995         if (pc == NULL)
1996                 return PLAYER_ERROR_OUT_OF_MEMORY;
1997
1998         while (retry_count--) {
1999                 ret = PLAYER_ERROR_NONE;
2000                 sock_fd = muse_client_new();
2001                 if (sock_fd <= INVALID_DEFAULT_VALUE) {
2002                         LOGE("connection failure %d", errno);
2003                         ret = PLAYER_ERROR_INVALID_OPERATION;
2004                         usleep(CONNECTION_TIME_OUT * G_TIME_SPAN_MILLISECOND);
2005                         goto ERROR_RETRY;
2006                 }
2007
2008                 if (muse_client_get_module_index(MODULE_NAME, &module_index) != MM_ERROR_NONE) {
2009                         LOGE("muse client get module index failed");
2010                         ret = PLAYER_ERROR_INVALID_OPERATION;
2011                         goto ERROR;
2012                 }
2013
2014                 PLAYER_SEND_MSG_ASYNC(api, sock_fd, ret,
2015                                                         MUSE_TYPE_INT, "module", module_index,
2016                                                         MUSE_TYPE_INT, "pid", pid);
2017                 if (ret == PLAYER_ERROR_INVALID_OPERATION)
2018                         goto ERROR;
2019
2020                 pc->cb_info = callback_new(sock_fd);
2021                 if (!pc->cb_info) {
2022                         LOGE("fail to create callback");
2023                         ret = PLAYER_ERROR_INVALID_OPERATION;
2024                         goto ERROR;
2025                 }
2026
2027                 ret = client_wait_for_server_ack(api, pc->cb_info, CREATE_CB_TIME_OUT);
2028                 if (ret == PLAYER_ERROR_INVALID_OPERATION)
2029                         goto ERROR_RETRY;
2030
2031                 if (!_player_event_queue_new(pc->cb_info)) {
2032                         LOGE("fail to create event queue");
2033                         ret = PLAYER_ERROR_INVALID_OPERATION;
2034                         goto ERROR;
2035                 }
2036
2037                 ret = client_wait_for_cb_return(api, pc->cb_info, &ret_buf, CALLBACK_TIME_OUT * 2);
2038                 if (ret == PLAYER_ERROR_NONE) {
2039                         intptr_t module_addr = 0;
2040                         *player = (player_h)pc;
2041                         if (player_msg_get_type(module_addr, ret_buf, POINTER)) {
2042                                 pc->cb_info->data_fd = muse_client_new_data_ch();
2043                                 if ((pc->cb_info->data_fd < 0) || (!muse_core_fd_is_valid(pc->cb_info->data_fd))) {
2044                                         LOGE("Failed to get data_fd");
2045                                         ret = PLAYER_ERROR_INVALID_OPERATION;
2046                                         goto ERROR;
2047                                 }
2048
2049                                 /* share the module addr info to the data_fd */
2050                                 PLAYER_SEND_MSG_ASYNC(MUSE_PLAYER_API_CREATE, pc->cb_info->data_fd, ret,
2051                                                                         MUSE_TYPE_POINTER, "module_addr", module_addr);
2052                                 if (ret != PLAYER_ERROR_NONE) {
2053                                         LOGE("Failed to send module address to the data fd");
2054                                         goto ERROR;
2055                                 }
2056                                 LOGD("Data channel fd %d, muse module addr %"PRIxPTR, pc->cb_info->data_fd, module_addr);
2057                         } else {
2058                                 ret = PLAYER_ERROR_INVALID_OPERATION;
2059                                 goto ERROR;
2060                         }
2061                         SERVER_TIMEOUT(pc) = MAX_SERVER_TIME_OUT; /* will be update after prepare phase. */
2062                 } else {
2063                         goto ERROR;
2064                 }
2065
2066                 pc->cb_info->bufmgr = tbm_bufmgr_init(-1);
2067                 pc->push_media_stream = FALSE;
2068
2069                 /* get display interface handle */
2070                 if (mm_display_interface_init(&DP_INTERFACE(pc)) != MM_ERROR_NONE)
2071                         LOGW("display interface init failed");
2072
2073                 g_free(ret_buf);
2074
2075                 LOGD("LEAVE 0x%X", ret);
2076                 return ret;
2077
2078 ERROR:
2079                 retry_count = 0;
2080 ERROR_RETRY:
2081                 if (pc && pc->cb_info) {
2082                         if (pc->cb_info->event_queue.running)
2083                                 _player_event_queue_destroy(pc->cb_info);
2084                         callback_destroy(pc->cb_info);
2085                         pc->cb_info = NULL;
2086                 } else if (sock_fd > INVALID_DEFAULT_VALUE) {
2087                         muse_client_close(sock_fd);
2088                 }
2089                 sock_fd = INVALID_DEFAULT_VALUE;
2090
2091                 g_free(ret_buf);
2092                 ret_buf = NULL;
2093                 LOGE("ret value : %d, retry #%d", ret, CONNECTION_RETRY - retry_count);
2094         }
2095         g_free(pc);
2096         pc = NULL;
2097         *player = NULL;
2098
2099         LOGD("LEAVE 0x%X", ret);
2100         return ret;
2101 }
2102
2103 int player_destroy(player_h player)
2104 {
2105         int ret = PLAYER_ERROR_NONE;
2106         muse_player_api_e api = MUSE_PLAYER_API_DESTROY;
2107         player_cli_s *pc = (player_cli_s *)player;
2108         char *ret_buf = NULL;
2109         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
2110
2111         PLAYER_INSTANCE_CHECK(player);
2112
2113         LOGD("ENTER %p", pc);
2114
2115         /* clear cb and release mem */
2116         set_null_user_cb_lock(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_SEEK);
2117         set_null_user_cb_lock(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_PREPARE);
2118         _player_release_internal_memory(pc, true);
2119
2120         if (DP_INTERFACE(pc)) {
2121                 PLAYER_GET_DISPLAY_TYPE(pc, display_type);
2122
2123                 if (display_type == MM_DISPLAY_TYPE_EVAS) {
2124                         player_unset_media_packet_video_frame_decoded_cb(player);
2125                         __player_unset_retrieve_buffer_cb(player);
2126                 }
2127
2128                 mm_display_interface_deinit(DP_INTERFACE(pc));
2129                 DP_INTERFACE(pc) = NULL;
2130         }
2131
2132         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2133
2134         if (CALLBACK_INFO(pc)) {
2135                 __player_remove_tsurf_list(pc);
2136                 _player_remove_idle_event(CALLBACK_INFO(pc), MUSE_PLAYER_EVENT_TYPE_NUM, true);
2137                 _player_event_queue_destroy(CALLBACK_INFO(pc));
2138                 tbm_bufmgr_deinit(TBM_BUFMGR(pc));
2139
2140                 callback_destroy(CALLBACK_INFO(pc));
2141         }
2142
2143         g_free(pc);
2144         pc = NULL;
2145
2146         g_free(ret_buf);
2147
2148         LOGD("LEAVE 0x%X", ret);
2149         return ret;
2150 }
2151
2152 int player_prepare_async(player_h player, player_prepared_cb callback, void *user_data)
2153 {
2154         int ret = PLAYER_ERROR_NONE;
2155         muse_player_api_e api = MUSE_PLAYER_API_PREPARE_ASYNC;
2156         player_cli_s *pc = (player_cli_s *)player;
2157         char *ret_buf = NULL;
2158
2159         PLAYER_INSTANCE_CHECK(player);
2160
2161         LOGD("ENTER %p %p", pc, callback);
2162
2163         if (pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_PREPARE]) {
2164                 LOGE("PLAYER_ERROR_INVALID_OPERATION (0x%08x) : preparing...", PLAYER_ERROR_INVALID_OPERATION);
2165                 return PLAYER_ERROR_INVALID_OPERATION;
2166         } else {
2167                 pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_PREPARE] = callback;
2168                 pc->cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_PREPARE] = user_data;
2169         }
2170         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2171         if (ret == PLAYER_ERROR_NONE) {
2172                 int timeout = 0;
2173                 player_msg_get_type(timeout, ret_buf, INT);
2174
2175                 LOGD("server timeout will be %d sec", timeout);
2176                 SERVER_TIMEOUT(pc) = timeout * G_TIME_SPAN_MILLISECOND;
2177         } else {
2178                 LOGW("failed to realize, so prepare cb will be released soon");
2179                 if (pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_PREPARE])
2180                         set_null_user_cb(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_PREPARE);
2181         }
2182
2183         g_free(ret_buf);
2184         return ret;
2185 }
2186
2187 int player_prepare(player_h player)
2188 {
2189         int ret = PLAYER_ERROR_NONE;
2190         muse_player_api_e api = MUSE_PLAYER_API_PREPARE;
2191         player_cli_s *pc = (player_cli_s *)player;
2192         char *ret_buf = NULL;
2193
2194         PLAYER_INSTANCE_CHECK(player);
2195
2196         LOGD("ENTER %p", pc);
2197
2198         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2199         if (ret == PLAYER_ERROR_NONE) {
2200                 int timeout = 0;
2201                 player_msg_get_type(timeout, ret_buf, INT);
2202
2203                 LOGD("server timeout will be %d sec", timeout);
2204                 SERVER_TIMEOUT(pc) = timeout * G_TIME_SPAN_MILLISECOND;
2205         }
2206
2207         g_free(ret_buf);
2208
2209         LOGD("LEAVE 0x%X", ret);
2210         return ret;
2211 }
2212
2213 int player_unprepare(player_h player)
2214 {
2215         int ret = PLAYER_ERROR_NONE;
2216         int mm_ret = MM_ERROR_NONE;
2217         muse_player_api_e api = MUSE_PLAYER_API_UNPREPARE;
2218         player_cli_s *pc = (player_cli_s *)player;
2219         char *ret_buf = NULL;
2220         player_state_e state = PLAYER_STATE_NONE;
2221         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
2222
2223         PLAYER_INSTANCE_CHECK(player);
2224
2225         LOGD("ENTER %p", pc);
2226
2227         if (_get_current_state(pc, &state) != PLAYER_ERROR_NONE) {
2228                 LOGE("Failed to get state");
2229                 ret = PLAYER_ERROR_INVALID_OPERATION;
2230                 goto EXIT;
2231         }
2232
2233         if (state < PLAYER_STATE_READY) {
2234                 if ((!CALLBACK_INFO(pc)) || (!CALLBACK_INFO(pc)->user_cb[MUSE_PLAYER_EVENT_TYPE_PREPARE])) {
2235                         LOGE("Invalid state %d", state);
2236                         ret = PLAYER_ERROR_INVALID_STATE;
2237                         goto EXIT;
2238                 }
2239         }
2240
2241         set_null_user_cb_lock(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_SEEK);
2242         set_null_user_cb_lock(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_PREPARE);
2243
2244         if (!DP_INTERFACE(pc))
2245                 goto _PLAYER_UNPREPARE;
2246
2247
2248         PLAYER_GET_DISPLAY_TYPE(pc, display_type);
2249
2250         if (display_type != MM_DISPLAY_TYPE_EVAS)
2251                 goto _PLAYER_UNPREPARE;
2252
2253         if (CALLBACK_INFO(pc)->dp_info.visible != PLAYER_VISIBLE_INFO_FALSE) {
2254                 mm_ret = mm_display_interface_evas_set_visible(DP_INTERFACE(pc), false);
2255                 if (mm_ret != MM_ERROR_NONE) {
2256                         LOGE("mm_display_interface_evas_set_visible failed 0x%x", mm_ret);
2257                         return PLAYER_ERROR_INVALID_OPERATION;
2258                 }
2259         }
2260
2261         mm_ret = mm_display_interface_evas_flush(DP_INTERFACE(pc), false);
2262         if (mm_ret != MM_ERROR_NONE) {
2263                 LOGE("mm_display_interface_evas_flush failed 0x%x", mm_ret);
2264                 return PLAYER_ERROR_INVALID_OPERATION;
2265         }
2266
2267 _PLAYER_UNPREPARE:
2268         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2269
2270         _player_release_internal_memory(pc, false);
2271         pc->cb_info->video_frame_pool_size = 0;
2272         __player_remove_tsurf_list(pc);
2273
2274         g_free(ret_buf);
2275
2276 EXIT:
2277         LOGD("LEAVE 0x%X", ret);
2278         return ret;
2279 }
2280
2281 /* 1. correct the protocol prefix to lower case
2282  * 2. remove 'file://' prefix
2283  * 3. covert '/opt/usr/media/xxx' file path to '/opt/usr/home/owner/media/xxx' */
2284 int _player_get_valid_path(const char *uri, char *valid_path)
2285 {
2286         gchar *file_path = NULL;
2287         GError *err = NULL;
2288         gchar *colon = NULL;
2289
2290         if (!uri || !valid_path) {
2291                 LOGD("invalid parameter");
2292                 return PLAYER_ERROR_INVALID_PARAMETER;
2293         }
2294
2295         if ((colon = strstr(uri, "://")) != NULL) {
2296                 gchar *protocol = g_ascii_strdown(uri, colon - uri);
2297
2298                 if (protocol) {
2299
2300                         file_path = g_strconcat(protocol, uri + strlen(protocol), NULL);
2301                         strncpy(valid_path, (file_path) ? (file_path) : (uri), MAX_URL_LEN - 1);
2302
2303                         g_free(protocol);
2304                         g_free(file_path);
2305                         file_path = NULL;
2306
2307                         if (strstr(valid_path, "file://")) { /* handle the 'file://' prefix */
2308
2309                                 file_path = g_filename_from_uri(valid_path, NULL, &err);
2310                                 if (!file_path || (err != NULL)) {
2311                                         SECURE_LOGE("Invalid URI '%s', err: %s", uri,
2312                                                         (err != NULL) ? err->message : "unknown error");
2313
2314                                         g_error_free(err);
2315                                         g_free(file_path);
2316
2317                                         return PLAYER_ERROR_INVALID_PARAMETER;
2318                                 }
2319                                 LOGD("get file path from uri");
2320                         } else {
2321                                 LOGD("use the original path.");
2322                                 return PLAYER_ERROR_NONE;
2323                         }
2324                 }
2325         }
2326
2327         if (storage_get_origin_internal_path((file_path) ? (file_path) : (uri), MAX_URL_LEN, valid_path) < 0) {
2328                 /* cannot convert path. use the original one. */
2329                 strncpy(valid_path, (file_path) ? (file_path) : (uri), MAX_URL_LEN - 1);
2330         } else {
2331                 /* need to use converted path. */
2332                 SECURE_LOGD("Converted path : %s -> %s", uri, valid_path);
2333         }
2334
2335         g_free(file_path);
2336
2337         return PLAYER_ERROR_NONE;
2338 }
2339
2340 int player_set_uri(player_h player, const char *uri)
2341 {
2342         int ret = PLAYER_ERROR_NONE;
2343         muse_player_api_e api = MUSE_PLAYER_API_SET_URI;
2344         player_cli_s *pc = (player_cli_s *)player;
2345         char *ret_buf = NULL;
2346         char path[MAX_URL_LEN] = {0, };
2347
2348         PLAYER_INSTANCE_CHECK(player);
2349         PLAYER_NULL_ARG_CHECK(uri);
2350
2351         LOGD("ENTER");
2352
2353         if (_player_get_valid_path(uri, path) != PLAYER_ERROR_NONE)
2354                 return PLAYER_ERROR_INVALID_PARAMETER;
2355
2356         SECURE_LOGD("new path : %s", path);
2357
2358         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_STRING, "path", (const char *)path);
2359         pc->push_media_stream = FALSE;
2360
2361         g_free(ret_buf);
2362         return ret;
2363 }
2364
2365 int player_set_memory_buffer(player_h player, const void *data, int size)
2366 {
2367         int ret = PLAYER_ERROR_NONE;
2368         muse_player_api_e api = MUSE_PLAYER_API_SET_MEMORY_BUFFER;
2369         player_cli_s *pc = (player_cli_s *)player;
2370         char *ret_buf = NULL;
2371         tbm_bo bo = NULL;
2372         tbm_bo_handle thandle;
2373         tbm_fd tfd = INVALID_DEFAULT_VALUE;
2374
2375         PLAYER_INSTANCE_CHECK(player);
2376         PLAYER_NULL_ARG_CHECK(data);
2377
2378         LOGD("ENTER");
2379
2380         /* before setting mem buffer, player state have to be checked. */
2381         PLAYER_STATE_CHECK(pc, PLAYER_STATE_IDLE);
2382
2383         if (SERVER_TBM_BO(pc)) {
2384                 LOGW("The previous memory buffer will be cleared.");
2385                 _player_deinit_memory_buffer(pc);
2386         }
2387
2388         bo = tbm_bo_alloc(pc->cb_info->bufmgr, size, TBM_BO_DEFAULT);
2389         if (bo == NULL) {
2390                 LOGE("TBM get error : bo is NULL");
2391                 return PLAYER_ERROR_INVALID_OPERATION;
2392         }
2393         thandle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2394         if (thandle.ptr == NULL) {
2395                 LOGE("TBM get error : handle pointer is NULL");
2396                 ret = PLAYER_ERROR_INVALID_OPERATION;
2397                 goto EXIT;
2398         }
2399         memcpy(thandle.ptr, data, size);
2400         tbm_bo_unmap(bo);
2401
2402         tfd = tbm_bo_export_fd(bo);
2403         if (tfd < 0) {
2404                 LOGE("tbm_bo_export_fd err 0x%x", tfd);
2405                 ret = PLAYER_ERROR_INVALID_OPERATION;
2406                 goto EXIT;
2407         }
2408
2409         PLAYER_SEND_MSG_WITH_TFD(api, pc, tfd, ret_buf, ret, MUSE_TYPE_INT, "size", size);
2410         pc->push_media_stream = FALSE;
2411
2412  EXIT:
2413         PLAYER_CLOSE_FD(tfd);
2414
2415         tbm_bo_unref(bo);
2416
2417         if (ret == PLAYER_ERROR_NONE) {
2418                 intptr_t bo_addr = 0;
2419                 if (player_msg_get_type(bo_addr, ret_buf, POINTER))
2420                         SERVER_TBM_BO(pc) = (intptr_t) bo_addr;
2421         }
2422
2423         g_free(ret_buf);
2424         return ret;
2425 }
2426
2427 static void _player_release_internal_memory(player_cli_s *pc, bool deinit_server_mem)
2428 {
2429         if (!pc)
2430                 return;
2431
2432         _del_mem(pc);
2433
2434         if (deinit_server_mem)
2435                 _player_deinit_memory_buffer(pc);
2436 }
2437
2438 static int _player_deinit_memory_buffer(player_cli_s *pc)
2439 {
2440         PLAYER_INSTANCE_CHECK(pc);
2441         int ret = PLAYER_ERROR_NONE;
2442         muse_player_api_e api = MUSE_PLAYER_API_DEINIT_MEMORY_BUFFER;
2443         intptr_t bo_addr = SERVER_TBM_BO(pc);
2444
2445         if (!bo_addr || !CALLBACK_INFO(pc))
2446                 return ret;
2447
2448         PLAYER_SEND_MSG_ASYNC(api, MSG_FD(pc), ret, MUSE_TYPE_POINTER, "bo_addr", bo_addr);
2449         SERVER_TBM_BO(pc) = 0;
2450
2451         return ret;
2452 }
2453
2454 int player_get_state(player_h player, player_state_e *pstate)
2455 {
2456         int ret = PLAYER_ERROR_NONE;
2457         player_cli_s *pc = (player_cli_s *)player;
2458
2459         PLAYER_INSTANCE_CHECK(player);
2460         PLAYER_NULL_ARG_CHECK(pstate);
2461
2462         LOGD("ENTER");
2463
2464         ret = _get_current_state(pc, pstate);
2465         return ret;
2466 }
2467
2468 int player_set_volume(player_h player, float left, float right)
2469 {
2470         int ret = PLAYER_ERROR_NONE;
2471         muse_player_api_e api = MUSE_PLAYER_API_SET_VOLUME;
2472         player_cli_s *pc = (player_cli_s *)player;
2473         char *ret_buf = NULL;
2474
2475         PLAYER_INSTANCE_CHECK(player);
2476         PLAYER_RANGE_ARG_CHECK(left, 0, 1.0);
2477         PLAYER_RANGE_ARG_CHECK(right, 0, 1.0);
2478
2479         /* not support to set different value into each channel */
2480         PLAYER_CHECK_CONDITION(left == right, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
2481
2482         LOGD("ENTER %f", left);
2483
2484         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
2485                                         MUSE_TYPE_DOUBLE, "volume", (double)left);
2486
2487         g_free(ret_buf);
2488         return ret;
2489 }
2490
2491 int player_get_volume(player_h player, float *left, float *right)
2492 {
2493         int ret = PLAYER_ERROR_NONE;
2494         muse_player_api_e api = MUSE_PLAYER_API_GET_VOLUME;
2495         player_cli_s *pc = (player_cli_s *)player;
2496         double volume = 0.0;
2497         char *ret_buf = NULL;
2498
2499         PLAYER_INSTANCE_CHECK(player);
2500         PLAYER_NULL_ARG_CHECK(left && right);
2501
2502         LOGD("ENTER");
2503
2504         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2505
2506         if (ret == PLAYER_ERROR_NONE) {
2507                 bool ret_val = true;
2508                 ret_val = _player_get_param_value(ret_buf,
2509                                                                         MUSE_TYPE_DOUBLE, "volume", (void *)&volume,
2510                                                                         INVALID_MUSE_TYPE_VALUE);
2511                 if (ret_val) {
2512                         *left = (float)volume;
2513                         *right = (float)volume;
2514                 } else {
2515                         LOGE("failed to get value from msg");
2516                         ret = PLAYER_ERROR_INVALID_OPERATION;
2517                 }
2518         }
2519
2520         g_free(ret_buf);
2521         return ret;
2522 }
2523
2524 int player_set_sound_stream_info(player_h player, sound_stream_info_h stream_info)
2525 {
2526         muse_player_api_e api = MUSE_PLAYER_API_SET_SOUND_STREAM_INFO;
2527         player_cli_s *pc = (player_cli_s *)player;
2528         bool is_available = false;
2529         char *ret_buf = NULL;
2530
2531         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SOUND_STREAM);
2532         PLAYER_INSTANCE_CHECK(player);
2533         PLAYER_NULL_ARG_CHECK(stream_info);
2534
2535         LOGD("ENTER");
2536
2537         /* check if stream_info is valid */
2538         int ret = sound_manager_is_available_stream_information(stream_info, NATIVE_API_PLAYER, &is_available);
2539         if (ret != SOUND_MANAGER_ERROR_NONE) {
2540                 LOGE("failed to checking available stream info");
2541                 return PLAYER_ERROR_INVALID_OPERATION;
2542         }
2543
2544         if (is_available == false) {
2545                 ret = PLAYER_ERROR_INVALID_PARAMETER;
2546         } else {
2547                 char *stream_type = NULL;
2548                 int stream_index = 0;
2549                 ret = sound_manager_get_type_from_stream_information(stream_info, &stream_type);
2550                 ret = sound_manager_get_index_from_stream_information(stream_info, &stream_index);
2551                 if (ret == SOUND_MANAGER_ERROR_NONE)
2552                         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
2553                                                         MUSE_TYPE_STRING, "stream_type", (const char *)stream_type,
2554                                                         MUSE_TYPE_INT, "stream_index", stream_index);
2555                 else
2556                         ret = PLAYER_ERROR_INVALID_OPERATION;
2557         }
2558
2559         LOGD("LEAVE ret: 0x%X", ret);
2560
2561         g_free(ret_buf);
2562         return ret;
2563
2564 }
2565
2566 int player_set_audio_latency_mode(player_h player, audio_latency_mode_e latency_mode)
2567 {
2568         int ret = PLAYER_ERROR_NONE;
2569         muse_player_api_e api = MUSE_PLAYER_API_SET_AUDIO_LATENCY_MODE;
2570         player_cli_s *pc = (player_cli_s *)player;
2571         char *ret_buf = NULL;
2572
2573         PLAYER_INSTANCE_CHECK(player);
2574         PLAYER_RANGE_ARG_CHECK(latency_mode, AUDIO_LATENCY_MODE_LOW, AUDIO_LATENCY_MODE_HIGH);
2575
2576         LOGD("ENTER");
2577
2578         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "latency_mode", (int)latency_mode);
2579         g_free(ret_buf);
2580         return ret;
2581 }
2582
2583 int player_get_audio_latency_mode(player_h player, audio_latency_mode_e *platency_mode)
2584 {
2585         int ret = PLAYER_ERROR_NONE;
2586         muse_player_api_e api = MUSE_PLAYER_API_GET_AUDIO_LATENCY_MODE;
2587         player_cli_s *pc = (player_cli_s *)player;
2588         char *ret_buf = NULL;
2589         int latency_mode = -1;
2590
2591         PLAYER_INSTANCE_CHECK(player);
2592         PLAYER_NULL_ARG_CHECK(platency_mode);
2593
2594         LOGD("ENTER");
2595
2596         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2597
2598         if (ret == PLAYER_ERROR_NONE) {
2599                 player_msg_get(latency_mode, ret_buf);
2600                 *platency_mode = latency_mode;
2601         }
2602
2603         g_free(ret_buf);
2604         return ret;
2605
2606 }
2607
2608 int player_start(player_h player)
2609 {
2610         int ret = PLAYER_ERROR_NONE;
2611         muse_player_api_e api = MUSE_PLAYER_API_START;
2612         player_cli_s *pc = (player_cli_s *)player;
2613         char *ret_buf = NULL;
2614         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
2615
2616         PLAYER_INSTANCE_CHECK(player);
2617
2618         LOGD("ENTER %p", pc);
2619
2620         if (!DP_INTERFACE(pc))
2621                 goto _PLAYER_START;
2622
2623         PLAYER_GET_DISPLAY_TYPE(pc, display_type);
2624
2625         if (display_type != MM_DISPLAY_TYPE_EVAS ||
2626                 CALLBACK_INFO(pc)->dp_info.visible == PLAYER_VISIBLE_INFO_FALSE)
2627                 goto _PLAYER_START;
2628
2629         /* set proper visible to evas renderer */
2630         if (mm_display_interface_evas_set_visible(DP_INTERFACE(pc), true) != MM_ERROR_NONE) {
2631                 LOGE("mm_display_interface_evas_set_visible failed");
2632                 return PLAYER_ERROR_INVALID_OPERATION;
2633         }
2634
2635         /* avoid setting true at all times, when player is resumed */
2636         CALLBACK_INFO(pc)->dp_info.visible = PLAYER_VISIBLE_INFO_TRUE;
2637
2638 _PLAYER_START:
2639         g_mutex_lock(&pc->cb_info->buffering_cb_mutex);
2640         pc->cb_info->drop_buffering_message = TRUE;
2641         g_mutex_unlock(&pc->cb_info->buffering_cb_mutex);
2642
2643         _player_remove_idle_event(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_BUFFERING, false);
2644
2645         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2646
2647         g_mutex_lock(&pc->cb_info->buffering_cb_mutex);
2648         pc->cb_info->drop_buffering_message = FALSE;
2649         g_mutex_unlock(&pc->cb_info->buffering_cb_mutex);
2650
2651         g_free(ret_buf);
2652
2653         LOGD("LEAVE 0x%X", ret);
2654         return ret;
2655 }
2656
2657 int player_stop(player_h player)
2658 {
2659         int ret = PLAYER_ERROR_NONE;
2660         int mm_ret = MM_ERROR_NONE;
2661         muse_player_api_e api = MUSE_PLAYER_API_STOP;
2662         player_cli_s *pc = (player_cli_s *)player;
2663         char *ret_buf = NULL;
2664         player_state_e state = PLAYER_STATE_NONE;
2665         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
2666
2667         PLAYER_INSTANCE_CHECK(player);
2668
2669         LOGD("ENTER %p", pc);
2670
2671         /* check player state */
2672         if (_get_current_state(pc, &state) != PLAYER_ERROR_NONE) {
2673                 LOGE("Failed to get state");
2674                 return PLAYER_ERROR_INVALID_OPERATION;
2675         }
2676
2677         if ((state != PLAYER_STATE_PLAYING) && (state != PLAYER_STATE_PAUSED)) {
2678                 LOGE("Invalid state %d", state);
2679                 return PLAYER_ERROR_INVALID_STATE;
2680         }
2681
2682         if (!DP_INTERFACE(pc))
2683                 goto _PLAYER_STOP;
2684
2685         PLAYER_GET_DISPLAY_TYPE(pc, display_type);
2686
2687         if (display_type != MM_DISPLAY_TYPE_EVAS ||
2688                 CALLBACK_INFO(pc)->dp_info.visible == PLAYER_VISIBLE_INFO_FALSE)
2689                 goto _PLAYER_STOP;
2690
2691         mm_ret = mm_display_interface_evas_set_visible(DP_INTERFACE(pc), false);
2692         if (mm_ret != MM_ERROR_NONE) {
2693                 LOGE("mm_display_interface_evas_set_visible failed 0x%x", mm_ret);
2694                 return PLAYER_ERROR_INVALID_OPERATION;
2695         }
2696
2697 _PLAYER_STOP:
2698         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2699         if (ret == PLAYER_ERROR_NONE)
2700                 set_null_user_cb_lock(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_SEEK);
2701
2702         g_free(ret_buf);
2703
2704         LOGD("LEAVE 0x%X", ret);
2705         return ret;
2706 }
2707
2708 int player_pause(player_h player)
2709 {
2710         int ret = PLAYER_ERROR_NONE;
2711         muse_player_api_e api = MUSE_PLAYER_API_PAUSE;
2712         player_cli_s *pc = (player_cli_s *)player;
2713         char *ret_buf = NULL;
2714
2715         PLAYER_INSTANCE_CHECK(player);
2716
2717         LOGD("ENTER %p", pc);
2718
2719         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2720         g_free(ret_buf);
2721
2722         LOGD("LEAVE 0x%X", ret);
2723         return ret;
2724 }
2725
2726 static int _set_play_position(player_h player, int64_t pos, bool accurate, player_seek_completed_cb callback, void *user_data)
2727 {
2728         int ret = PLAYER_ERROR_NONE;
2729         muse_player_api_e api = MUSE_PLAYER_API_SET_PLAY_POSITION;
2730         player_cli_s *pc = (player_cli_s *)player;
2731         char *ret_buf = NULL;
2732
2733         PLAYER_INSTANCE_CHECK(player);
2734         PLAYER_CHECK_CONDITION(pos >= 0, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
2735
2736         LOGD("ENTER %p", pc);
2737
2738         if (!pc->cb_info) {
2739                 LOGE("cb_info is null");
2740                 return PLAYER_ERROR_INVALID_OPERATION;
2741         }
2742
2743         g_mutex_lock(&pc->cb_info->seek_cb_mutex);
2744         if ((pc->push_media_stream == FALSE) &&
2745                 (pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_SEEK])) {
2746                 LOGE("PLAYER_ERROR_SEEK_FAILED (0x%08x) : seeking...", PLAYER_ERROR_SEEK_FAILED);
2747                 g_mutex_unlock(&pc->cb_info->seek_cb_mutex);
2748                 return PLAYER_ERROR_SEEK_FAILED;
2749         } else {
2750                 if (pc->push_media_stream == TRUE)
2751                         pc->cb_info->seek_cb_state = PLAYER_SEEK_CB_STATE_DROP;
2752                 else
2753                         pc->cb_info->seek_cb_state = PLAYER_SEEK_CB_STATE_WAIT;
2754                 LOGI("Event type : %d, pos : %"PRId64", accurate : %d", MUSE_PLAYER_EVENT_TYPE_SEEK, pos, accurate);
2755                 pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_SEEK] = callback;
2756                 pc->cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_SEEK] = user_data;
2757         }
2758         g_mutex_unlock(&pc->cb_info->seek_cb_mutex);
2759
2760         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
2761                                         MUSE_TYPE_INT64, "pos", pos,
2762                                         MUSE_TYPE_INT, "accurate", (int)accurate);
2763
2764         if (ret != PLAYER_ERROR_NONE) {
2765                 g_mutex_lock(&pc->cb_info->seek_cb_mutex);
2766                 set_null_user_cb(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_SEEK);
2767                 g_mutex_unlock(&pc->cb_info->seek_cb_mutex);
2768         }
2769
2770         if (pc->push_media_stream == TRUE)
2771                 _player_event_queue_remove(&pc->cb_info->event_queue, MUSE_PLAYER_EVENT_TYPE_SEEK);
2772
2773         g_free(ret_buf);
2774
2775         g_mutex_lock(&pc->cb_info->seek_cb_mutex);
2776         pc->cb_info->seek_cb_state = PLAYER_SEEK_CB_STATE_NONE;
2777         g_mutex_unlock(&pc->cb_info->seek_cb_mutex);
2778
2779         LOGD("LEAVE 0x%X", ret);
2780         return ret;
2781 }
2782
2783
2784 int player_set_play_position(player_h player, int milliseconds, bool accurate, player_seek_completed_cb callback, void *user_data)
2785 {
2786         int ret = PLAYER_ERROR_NONE;
2787         int64_t pos = (int64_t)(milliseconds * G_GINT64_CONSTANT(1000000));
2788
2789         PLAYER_INSTANCE_CHECK(player);
2790         PLAYER_CHECK_CONDITION(milliseconds >= 0, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
2791
2792         LOGD("ENTER");
2793
2794         ret = _set_play_position(player, pos, accurate, callback, user_data);
2795
2796         LOGD("LEAVE 0x%X", ret);
2797         return ret;
2798 }
2799
2800 int player_set_play_position_nsec(player_h player, int64_t nanoseconds, bool accurate, player_seek_completed_cb callback, void *user_data)
2801 {
2802         int ret = PLAYER_ERROR_NONE;
2803         int64_t pos = nanoseconds;
2804
2805         PLAYER_INSTANCE_CHECK(player);
2806         PLAYER_CHECK_CONDITION(nanoseconds >= 0, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
2807
2808         LOGD("ENTER");
2809
2810         ret = _set_play_position(player, pos, accurate, callback, user_data);
2811
2812         LOGD("LEAVE 0x%X", ret);
2813         return ret;
2814 }
2815
2816 static int _get_play_position(player_h player, int64_t *pos)
2817 {
2818         int ret = PLAYER_ERROR_NONE;
2819         muse_player_api_e api = MUSE_PLAYER_API_GET_PLAY_POSITION;
2820         player_cli_s *pc = (player_cli_s *)player;
2821         char *ret_buf = NULL;
2822
2823         PLAYER_INSTANCE_CHECK(player);
2824         PLAYER_NULL_ARG_CHECK(pos);
2825
2826         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2827
2828         if (ret == PLAYER_ERROR_NONE) {
2829                 bool ret_val = true;
2830                 ret_val = _player_get_param_value(ret_buf,
2831                                                                         MUSE_TYPE_INT64, "pos", (void *)pos,
2832                                                                         INVALID_MUSE_TYPE_VALUE);
2833                 if (!ret_val)
2834                         ret = PLAYER_ERROR_INVALID_OPERATION;
2835         }
2836
2837         g_free(ret_buf);
2838         return ret;
2839 }
2840
2841
2842 int player_get_play_position(player_h player, int *milliseconds)
2843 {
2844         int ret = PLAYER_ERROR_NONE;
2845         int64_t pos = 0;
2846
2847         PLAYER_INSTANCE_CHECK(player);
2848         PLAYER_NULL_ARG_CHECK(milliseconds);
2849
2850         /* LOGD("ENTER"); */
2851
2852         ret = _get_play_position(player, &pos);
2853         if (ret == PLAYER_ERROR_NONE)
2854                 *milliseconds = (int)(pos / G_GINT64_CONSTANT(1000000));
2855
2856         return ret;
2857 }
2858
2859 int player_get_play_position_nsec(player_h player, int64_t *nanoseconds)
2860 {
2861         int ret = PLAYER_ERROR_NONE;
2862         int64_t pos = 0;
2863
2864         PLAYER_INSTANCE_CHECK(player);
2865         PLAYER_NULL_ARG_CHECK(nanoseconds);
2866
2867         /* LOGD("ENTER"); */
2868
2869         ret = _get_play_position(player, &pos);
2870         if (ret == PLAYER_ERROR_NONE)
2871                 *nanoseconds = pos;
2872
2873         return ret;
2874 }
2875
2876 int player_set_mute(player_h player, bool muted)
2877 {
2878         int ret = PLAYER_ERROR_NONE;
2879         muse_player_api_e api = MUSE_PLAYER_API_SET_MUTE;
2880         player_cli_s *pc = (player_cli_s *)player;
2881         char *ret_buf = NULL;
2882         int mute = (int)muted;
2883
2884         PLAYER_INSTANCE_CHECK(player);
2885
2886         LOGD("ENTER");
2887
2888         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "mute", mute);
2889         g_free(ret_buf);
2890         return ret;
2891 }
2892
2893 int player_is_muted(player_h player, bool *muted)
2894 {
2895         int ret = PLAYER_ERROR_NONE;
2896         muse_player_api_e api = MUSE_PLAYER_API_IS_MUTED;
2897         player_cli_s *pc = (player_cli_s *)player;
2898         char *ret_buf = NULL;
2899         int mute = -1;
2900
2901         PLAYER_INSTANCE_CHECK(player);
2902         PLAYER_NULL_ARG_CHECK(muted);
2903
2904         LOGD("ENTER");
2905
2906         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2907         if (ret == PLAYER_ERROR_NONE) {
2908                 player_msg_get(mute, ret_buf);
2909                 *muted = (bool)mute;
2910         }
2911
2912         g_free(ret_buf);
2913         return ret;
2914 }
2915
2916 int player_set_looping(player_h player, bool looping)
2917 {
2918         int ret = PLAYER_ERROR_NONE;
2919         muse_player_api_e api = MUSE_PLAYER_API_SET_LOOPING;
2920         player_cli_s *pc = (player_cli_s *)player;
2921         char *ret_buf = NULL;
2922
2923         PLAYER_INSTANCE_CHECK(player);
2924
2925         LOGD("ENTER");
2926
2927         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "looping", (int)looping);
2928         g_free(ret_buf);
2929         return ret;
2930 }
2931
2932 int player_is_looping(player_h player, bool *plooping)
2933 {
2934         int ret = PLAYER_ERROR_NONE;
2935         muse_player_api_e api = MUSE_PLAYER_API_IS_LOOPING;
2936         player_cli_s *pc = (player_cli_s *)player;
2937         char *ret_buf = NULL;
2938         int looping = 0;
2939
2940         PLAYER_INSTANCE_CHECK(player);
2941         PLAYER_NULL_ARG_CHECK(plooping);
2942
2943         LOGD("ENTER");
2944
2945         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2946         if (ret == PLAYER_ERROR_NONE) {
2947                 player_msg_get(looping, ret_buf);
2948                 *plooping = looping;
2949         }
2950         g_free(ret_buf);
2951         return ret;
2952 }
2953
2954 static int _get_duration(player_h player, int64_t *duration)
2955 {
2956         int ret = PLAYER_ERROR_NONE;
2957         muse_player_api_e api = MUSE_PLAYER_API_GET_DURATION;
2958         player_cli_s *pc = (player_cli_s *)player;
2959         char *ret_buf = NULL;
2960
2961         PLAYER_INSTANCE_CHECK(player);
2962         PLAYER_NULL_ARG_CHECK(duration);
2963
2964         LOGD("ENTER");
2965
2966         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
2967         if (ret == PLAYER_ERROR_NONE) {
2968                 bool ret_val = true;
2969                 ret_val = _player_get_param_value(ret_buf,
2970                                                                         MUSE_TYPE_INT64, "duration", (void *)duration,
2971                                                                         INVALID_MUSE_TYPE_VALUE);
2972                 if (!ret_val)
2973                         ret = PLAYER_ERROR_INVALID_OPERATION;
2974         }
2975
2976         g_free(ret_buf);
2977         return ret;
2978 }
2979
2980
2981 int player_get_duration(player_h player, int *milliseconds)
2982 {
2983         int ret = PLAYER_ERROR_NONE;
2984         int64_t duration = 0; /* nsec */
2985
2986         PLAYER_INSTANCE_CHECK(player);
2987         PLAYER_NULL_ARG_CHECK(milliseconds);
2988
2989         LOGD("ENTER");
2990
2991         ret = _get_duration(player, &duration);
2992         if (ret == PLAYER_ERROR_NONE) {
2993                 /* convert time from ns to ms */
2994                 *milliseconds = (int)(duration / G_GINT64_CONSTANT(1000000));
2995         }
2996
2997         LOGD("LEAVE 0x%X", ret);
2998         return ret;
2999 }
3000
3001 int player_get_duration_nsec(player_h player, int64_t *nanoseconds)
3002 {
3003         int ret = PLAYER_ERROR_NONE;
3004         int64_t duration = 0; /* nsec */
3005
3006         PLAYER_INSTANCE_CHECK(player);
3007         PLAYER_NULL_ARG_CHECK(nanoseconds);
3008
3009         LOGD("ENTER");
3010
3011         ret = _get_duration(player, &duration);
3012         if (ret == PLAYER_ERROR_NONE)
3013                 *nanoseconds = duration;
3014
3015         LOGD("LEAVE 0x%X", ret);
3016         return ret;
3017 }
3018
3019 /* The player_display_type_e is different at wearable profile */
3020 int _player_convert_display_type(player_display_type_e type, mm_display_type_e *out_type)
3021 {
3022         int ret = PLAYER_ERROR_NONE;
3023
3024         PLAYER_NULL_ARG_CHECK(out_type);
3025
3026         switch (type) {
3027         case PLAYER_DISPLAY_TYPE_OVERLAY:
3028                 *out_type = MM_DISPLAY_TYPE_OVERLAY;
3029                 break;
3030         case PLAYER_DISPLAY_TYPE_EVAS:
3031                 *out_type = MM_DISPLAY_TYPE_EVAS;
3032                 break;
3033         case PLAYER_DISPLAY_TYPE_NONE:
3034                 *out_type = MM_DISPLAY_TYPE_NONE;
3035                 break;
3036         default:
3037                 ret = PLAYER_ERROR_INVALID_PARAMETER;
3038                 break;
3039         }
3040
3041         LOGD("display type(%d) -> (%d)", type, *out_type);
3042
3043         return ret;
3044 }
3045
3046 int player_set_display(player_h player, player_display_type_e type, player_display_h display)
3047 {
3048         int ret = PLAYER_ERROR_NONE;
3049         int mm_ret = MM_ERROR_NONE;
3050         muse_player_api_e api = MUSE_PLAYER_API_SET_DISPLAY;
3051         player_cli_s *pc = (player_cli_s *)player;
3052         char *ret_buf = NULL;
3053         wl_win_msg_type wl_win;
3054         char *wl_win_msg = (char *)&wl_win;
3055         mm_display_type_e conv_type = MM_DISPLAY_TYPE_NONE;
3056         int arr_msg_len = 0;
3057         pid_t pid = getpid();
3058         pid_t tid = syscall(SYS_gettid);
3059
3060         PLAYER_INSTANCE_CHECK(player);
3061
3062         if (type != PLAYER_DISPLAY_TYPE_NONE) {
3063                 LOGD("Check if API is called in main thread. pid [%d], tid [%d]", pid, tid);
3064                 if (pid != tid) {
3065                         LOGE("API isn't called in main thread");
3066                         return PLAYER_ERROR_INVALID_OPERATION;
3067                 }
3068         }
3069
3070         /* check display interface handle */
3071         if (!DP_INTERFACE(pc)) {
3072                 LOGE("display interface not supported");
3073                 return PLAYER_ERROR_INVALID_OPERATION;
3074         }
3075
3076         LOGD("ENTER type: %d", type);
3077
3078         /* before setting display, player state have to be checked. */
3079         PLAYER_STATE_CHECK(pc, PLAYER_STATE_IDLE);
3080
3081         ret = _player_convert_display_type(type, &conv_type);
3082         if (ret != PLAYER_ERROR_NONE)
3083                 return ret;
3084
3085         if (conv_type != MM_DISPLAY_TYPE_NONE) {
3086                 if (!display) {
3087                         LOGE("type[%d] NULL handle for display", type);
3088                         return PLAYER_ERROR_INVALID_PARAMETER;
3089                 }
3090
3091                 mm_ret = mm_display_interface_set_display(DP_INTERFACE(pc), conv_type, display, &wl_win.surface_id);
3092                 if (mm_ret != MM_ERROR_NONE) {
3093                         LOGE("[INVALID_OPERATION] set display failed[0x%x]", mm_ret);
3094                         return PLAYER_ERROR_INVALID_OPERATION;
3095                 }
3096
3097                 if (conv_type == MM_DISPLAY_TYPE_EVAS) {
3098                         /* before evas handle is created, user could set display information */
3099                         player_display_mode_e mode = PLAYER_DISPLAY_MODE_LETTER_BOX;
3100                         player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
3101                         bool visible = false;
3102
3103                         ret = player_get_display_mode(player, &mode);
3104                         ret |= player_get_display_rotation(player, &rotation);
3105                         ret |= player_is_display_visible(player, &visible);
3106
3107                         if (ret != PLAYER_ERROR_NONE) {
3108                                 LOGE("get current display settings");
3109                                 return PLAYER_ERROR_INVALID_OPERATION;
3110                         }
3111
3112                         LOGD("current setting : mode %d, rotation %d, visible %d, roi %d,%d,%dx%d",
3113                                 mode, rotation, visible,
3114                                 CALLBACK_INFO(pc)->dp_info.roi_x,
3115                                 CALLBACK_INFO(pc)->dp_info.roi_y,
3116                                 CALLBACK_INFO(pc)->dp_info.roi_w,
3117                                 CALLBACK_INFO(pc)->dp_info.roi_h);
3118
3119                         mm_ret = mm_display_interface_evas_set_mode(DP_INTERFACE(pc), mode);
3120                         mm_ret |= mm_display_interface_evas_set_rotation(DP_INTERFACE(pc), rotation);
3121                         mm_ret |= mm_display_interface_evas_set_visible(DP_INTERFACE(pc), visible);
3122                         if (mode == PLAYER_DISPLAY_MODE_DST_ROI) {
3123                                 mm_ret |= mm_display_interface_evas_set_roi_area(DP_INTERFACE(pc),
3124                                         CALLBACK_INFO(pc)->dp_info.roi_x, CALLBACK_INFO(pc)->dp_info.roi_y,
3125                                         CALLBACK_INFO(pc)->dp_info.roi_w, CALLBACK_INFO(pc)->dp_info.roi_h);
3126                         }
3127
3128                         if (mm_ret != MM_ERROR_NONE) {
3129                                 LOGE("set mm_display_interface failed");
3130                                 return PLAYER_ERROR_INVALID_OPERATION;
3131                         }
3132
3133                         if (player_set_media_packet_video_frame_decoded_cb(player,
3134                                 __player_media_packet_video_decoded_cb, player) != MM_ERROR_NONE) {
3135                                 LOGE("fail to set decoded callback");
3136                                 return PLAYER_ERROR_INVALID_OPERATION;
3137                         }
3138
3139                         if (__player_set_retrieve_buffer_cb(player, __retrieve_buffer_cb, pc))
3140                                 LOGW("fail to set __retrieve_buffer_cb");
3141                 }
3142         }
3143
3144         wl_win.type = conv_type;
3145
3146         arr_msg_len = (sizeof(wl_win_msg_type) / sizeof(int) + (sizeof(wl_win_msg_type) % sizeof(int) ? 1 : 0));
3147         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
3148                 MUSE_TYPE_ARRAY, "wl_win_msg", arr_msg_len, (int *)wl_win_msg);
3149
3150         g_free(ret_buf);
3151
3152         return ret;
3153 }
3154
3155 int player_set_display_mode(player_h player, player_display_mode_e mode)
3156 {
3157         int ret = PLAYER_ERROR_NONE;
3158         int mm_ret = MM_ERROR_NONE;
3159         muse_player_api_e api = MUSE_PLAYER_API_SET_DISPLAY_MODE;
3160         player_cli_s *pc = (player_cli_s *)player;
3161         char *ret_buf = NULL;
3162         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
3163
3164         PLAYER_INSTANCE_CHECK(player);
3165         PLAYER_RANGE_ARG_CHECK(mode, PLAYER_DISPLAY_MODE_LETTER_BOX, PLAYER_DISPLAY_MODE_DST_ROI);
3166
3167         LOGD("ENTER");
3168
3169         PLAYER_GET_DISPLAY_TYPE(pc, display_type);
3170
3171         if (display_type == MM_DISPLAY_TYPE_EVAS) {
3172                 mm_ret = mm_display_interface_evas_set_mode(DP_INTERFACE(pc), mode);
3173                 if (mm_ret != MM_ERROR_NONE) {
3174                         LOGE("mm_display_interface_evas_set_mode failed 0x%x", mm_ret);
3175                         return PLAYER_ERROR_INVALID_OPERATION;
3176                 }
3177         }
3178
3179         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "mode", (int)mode);
3180
3181         g_free(ret_buf);
3182
3183         return ret;
3184 }
3185
3186 int player_get_display_mode(player_h player, player_display_mode_e *pmode)
3187 {
3188         int ret = PLAYER_ERROR_NONE;
3189         muse_player_api_e api = MUSE_PLAYER_API_GET_DISPLAY_MODE;
3190         player_cli_s *pc = (player_cli_s *)player;
3191         char *ret_buf = NULL;
3192         int mode = -1;
3193
3194         PLAYER_INSTANCE_CHECK(player);
3195         PLAYER_NULL_ARG_CHECK(pmode);
3196
3197         LOGD("ENTER");
3198
3199         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3200
3201         if (ret == PLAYER_ERROR_NONE) {
3202                 player_msg_get_type(mode, ret_buf, INT);
3203                 *pmode = mode;
3204         }
3205
3206         g_free(ret_buf);
3207
3208         return ret;
3209 }
3210
3211 int player_set_video_roi_area(player_h player, double x_scale, double y_scale,
3212                 double w_scale, double h_scale)
3213 {
3214         int ret = PLAYER_ERROR_NONE;
3215         muse_player_api_e api = MUSE_PLAYER_API_SET_VIDEO_ROI_AREA;
3216         player_cli_s *pc = (player_cli_s *)player;
3217         char *ret_buf = NULL;
3218         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
3219
3220         PLAYER_INSTANCE_CHECK(player);
3221
3222         LOGD("ENTER");
3223
3224         PLAYER_GET_DISPLAY_TYPE(pc, display_type);
3225
3226         if (display_type == MM_DISPLAY_TYPE_EVAS) {
3227                 LOGE("Display type is EVAS, video display interface is not supported");
3228                 return PLAYER_ERROR_INVALID_OPERATION;
3229         }
3230
3231         if (!_player_video_roi_area_is_valid(x_scale, y_scale, w_scale, h_scale))
3232                 return PLAYER_ERROR_INVALID_PARAMETER;
3233
3234         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
3235                         MUSE_TYPE_DOUBLE, "x_scale", x_scale,
3236                         MUSE_TYPE_DOUBLE, "y_scale", y_scale,
3237                         MUSE_TYPE_DOUBLE, "w_scale", w_scale,
3238                         MUSE_TYPE_DOUBLE, "h_scale", h_scale);
3239
3240         g_free(ret_buf);
3241
3242         return ret;
3243 }
3244
3245
3246 int player_get_video_roi_area(player_h player, double *x_scale, double *y_scale,
3247                 double *w_scale, double *h_scale)
3248 {
3249         int ret = PLAYER_ERROR_NONE;
3250         muse_player_api_e api = MUSE_PLAYER_API_GET_VIDEO_ROI_AREA;
3251         player_cli_s *pc = (player_cli_s *)player;
3252         char *ret_buf = NULL;
3253         double scale_x = 0, scale_y = 0, scale_w = 0, scale_h = 0;
3254
3255         PLAYER_INSTANCE_CHECK(player);
3256         PLAYER_NULL_ARG_CHECK(x_scale && y_scale && w_scale && h_scale);
3257
3258         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3259
3260         if (ret == PLAYER_ERROR_NONE) {
3261                 if (player_msg_get_type(scale_x, ret_buf, DOUBLE))
3262                         *x_scale = scale_x;
3263                 else
3264                         LOGE("failed to get value from msg");
3265                 if (player_msg_get_type(scale_y, ret_buf, DOUBLE))
3266                         *y_scale = scale_y;
3267                 else
3268                         LOGE("failed to get value from msg");
3269                 if (player_msg_get_type(scale_w, ret_buf, DOUBLE))
3270                         *w_scale = scale_w;
3271                 else
3272                         LOGE("failed to get value from msg");
3273                 if (player_msg_get_type(scale_h, ret_buf, DOUBLE))
3274                         *h_scale = scale_h;
3275                 else
3276                         LOGE("failed to get value from msg");
3277         }
3278
3279         g_free(ret_buf);
3280
3281         return ret;
3282 }
3283
3284
3285 int player_set_display_roi_area(player_h player, int x, int y, int width, int height)
3286 {
3287         int ret = PLAYER_ERROR_NONE;
3288         int mm_ret = MM_ERROR_NONE;
3289         muse_player_api_e api = MUSE_PLAYER_API_SET_DISPLAY_ROI_AREA;
3290         player_cli_s *pc = (player_cli_s *)player;
3291         char *ret_buf = NULL;
3292         wl_win_msg_type wl_win;
3293         char *wl_win_msg = (char *)&wl_win;
3294         int arr_msg_len = 0;
3295         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
3296
3297         PLAYER_INSTANCE_CHECK(player);
3298         PLAYER_CHECK_CONDITION(width > 0 && height > 0, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
3299
3300         LOGD("ENTER");
3301
3302         PLAYER_GET_DISPLAY_TYPE(pc, display_type);
3303
3304         if (display_type == MM_DISPLAY_TYPE_EVAS) {
3305                 mm_ret = mm_display_interface_evas_set_roi_area(DP_INTERFACE(pc), x, y, width, height);
3306                 if (mm_ret == MM_ERROR_EVASRENDER_INVALID_ARGUMENT)
3307                         return PLAYER_ERROR_INVALID_PARAMETER;
3308                 else if (mm_ret != MM_ERROR_NONE)
3309                         return PLAYER_ERROR_INVALID_OPERATION;
3310         }
3311
3312         wl_win.win_roi_x = x;
3313         wl_win.win_roi_y = y;
3314         wl_win.win_roi_width = width;
3315         wl_win.win_roi_height = height;
3316
3317         arr_msg_len = (sizeof(wl_win_msg_type) / sizeof(int) + (sizeof(wl_win_msg_type) % sizeof(int) ? 1 : 0));
3318         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
3319                 MUSE_TYPE_ARRAY, "wl_win_msg", arr_msg_len, (int *)wl_win_msg);
3320
3321         if (ret == PLAYER_ERROR_NONE) {
3322                 CALLBACK_INFO(pc)->dp_info.roi_x = x;
3323                 CALLBACK_INFO(pc)->dp_info.roi_y = y;
3324                 CALLBACK_INFO(pc)->dp_info.roi_w = width;
3325                 CALLBACK_INFO(pc)->dp_info.roi_h = height;
3326         }
3327
3328         g_free(ret_buf);
3329
3330         return ret;
3331 }
3332
3333 int player_set_playback_rate(player_h player, float rate)
3334 {
3335         int ret = PLAYER_ERROR_NONE;
3336         muse_player_api_e api = MUSE_PLAYER_API_SET_PLAYBACK_RATE;
3337         player_cli_s *pc = (player_cli_s *)player;
3338         char *ret_buf = NULL;
3339
3340         PLAYER_INSTANCE_CHECK(player);
3341         PLAYER_RANGE_ARG_CHECK(rate, -5.0, 5.0);
3342
3343         LOGD("ENTER");
3344         if (rate != 0) {
3345                 PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_DOUBLE, "rate", (double)rate);
3346                 g_free(ret_buf);
3347         }
3348         LOGD("LEAVE 0x%X", ret);
3349         return ret;
3350 }
3351
3352 int player_set_display_rotation(player_h player, player_display_rotation_e rotation)
3353 {
3354         int ret = PLAYER_ERROR_NONE;
3355         int mm_ret = MM_ERROR_NONE;
3356         muse_player_api_e api = MUSE_PLAYER_API_SET_DISPLAY_ROTATION;
3357         player_cli_s *pc = (player_cli_s *)player;
3358         char *ret_buf = NULL;
3359         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
3360
3361         PLAYER_INSTANCE_CHECK(player);
3362         PLAYER_RANGE_ARG_CHECK(rotation, PLAYER_DISPLAY_ROTATION_NONE, PLAYER_DISPLAY_ROTATION_270);
3363
3364         LOGD("ENTER");
3365
3366         PLAYER_GET_DISPLAY_TYPE(pc, display_type);
3367
3368         if (display_type == MM_DISPLAY_TYPE_EVAS) {
3369                 mm_ret = mm_display_interface_evas_set_rotation(DP_INTERFACE(pc), rotation);
3370                 if (mm_ret != MM_ERROR_NONE) {
3371                         LOGE("mm_display_interface_evas_set_rotation failed 0x%x", mm_ret);
3372                         return PLAYER_ERROR_INVALID_OPERATION;
3373                 }
3374         }
3375
3376         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "rotation", (int)rotation);
3377
3378         g_free(ret_buf);
3379
3380         return ret;
3381 }
3382
3383 int player_get_display_rotation(player_h player, player_display_rotation_e *protation)
3384 {
3385         int ret = PLAYER_ERROR_NONE;
3386         player_cli_s *pc = (player_cli_s *)player;
3387         muse_player_api_e api = MUSE_PLAYER_API_GET_DISPLAY_ROTATION;
3388         char *ret_buf = NULL;
3389         int rotation = -1;
3390
3391         PLAYER_INSTANCE_CHECK(player);
3392         PLAYER_NULL_ARG_CHECK(protation);
3393
3394         LOGD("ENTER");
3395
3396         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3397
3398         if (ret == PLAYER_ERROR_NONE) {
3399                 player_msg_get_type(rotation, ret_buf, INT);
3400                 *protation = rotation;
3401         }
3402
3403         g_free(ret_buf);
3404
3405         return ret;
3406 }
3407
3408 int player_set_display_visible(player_h player, bool visible)
3409 {
3410         int ret = PLAYER_ERROR_NONE;
3411         int mm_ret = MM_ERROR_NONE;
3412         player_cli_s *pc = (player_cli_s *)player;
3413         muse_player_api_e api = MUSE_PLAYER_API_SET_DISPLAY_VISIBLE;
3414         char *ret_buf = NULL;
3415         mm_display_type_e display_type = MM_DISPLAY_TYPE_NONE;
3416
3417         PLAYER_INSTANCE_CHECK(player);
3418
3419         LOGD("ENTER");
3420
3421         PLAYER_GET_DISPLAY_TYPE(pc, display_type);
3422
3423         if (display_type == MM_DISPLAY_TYPE_EVAS) {
3424                 mm_ret = mm_display_interface_evas_set_visible(DP_INTERFACE(pc), visible);
3425                 if (mm_ret != MM_ERROR_NONE) {
3426                         LOGE("mm_display_interface_evas_set_visible failed 0x%x", mm_ret);
3427                         return PLAYER_ERROR_INVALID_OPERATION;
3428                 }
3429         }
3430
3431         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "visible", (int)visible);
3432
3433         g_free(ret_buf);
3434
3435         if (ret == PLAYER_ERROR_NONE)
3436                 CALLBACK_INFO(pc)->dp_info.visible = visible ? PLAYER_VISIBLE_INFO_TRUE : PLAYER_VISIBLE_INFO_FALSE;
3437
3438         return ret;
3439 }
3440
3441 int player_is_display_visible(player_h player, bool *pvisible)
3442 {
3443         int ret = PLAYER_ERROR_NONE;
3444         player_cli_s *pc = (player_cli_s *)player;
3445         muse_player_api_e api = MUSE_PLAYER_API_IS_DISPLAY_VISIBLE;
3446         char *ret_buf = NULL;
3447         int value = -1;
3448
3449         PLAYER_INSTANCE_CHECK(player);
3450         PLAYER_NULL_ARG_CHECK(pvisible);
3451
3452         LOGD("ENTER");
3453
3454         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3455
3456         if (ret == PLAYER_ERROR_NONE) {
3457                 player_msg_get_type(value, ret_buf, INT);
3458
3459                 if (value)
3460                         *pvisible = TRUE;
3461                 else
3462                         *pvisible = FALSE;
3463         }
3464
3465         g_free(ret_buf);
3466
3467         return ret;
3468 }
3469
3470 int player_get_content_info(player_h player, player_content_info_e key, char **pvalue)
3471 {
3472         int ret = PLAYER_ERROR_NONE;
3473         muse_player_api_e api = MUSE_PLAYER_API_GET_CONTENT_INFO;
3474         player_cli_s *pc = (player_cli_s *)player;
3475         char *ret_buf = NULL;
3476         char value[MUSE_MSG_MAX_LENGTH] = { 0, };
3477
3478         PLAYER_INSTANCE_CHECK(player);
3479         PLAYER_NULL_ARG_CHECK(pvalue);
3480
3481         LOGD("ENTER");
3482
3483         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "key", (int)key);
3484         if (ret == PLAYER_ERROR_NONE) {
3485                 player_msg_get_string(value, ret_buf);
3486                 *pvalue = strndup(value, MUSE_MSG_MAX_LENGTH);
3487         }
3488         g_free(ret_buf);
3489         return ret;
3490 }
3491
3492 int player_get_codec_info(player_h player, char **paudio_codec, char **pvideo_codec)
3493 {
3494         int ret = PLAYER_ERROR_NONE;
3495         muse_player_api_e api = MUSE_PLAYER_API_GET_CODEC_INFO;
3496         player_cli_s *pc = (player_cli_s *)player;
3497         char *ret_buf = NULL;
3498         char video_codec[MUSE_MSG_MAX_LENGTH] = { 0, };
3499         char audio_codec[MUSE_MSG_MAX_LENGTH] = { 0, };
3500         bool ret_val = TRUE;
3501
3502         PLAYER_INSTANCE_CHECK(player);
3503         PLAYER_NULL_ARG_CHECK(paudio_codec || pvideo_codec);
3504
3505         LOGD("ENTER");
3506
3507         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3508         if (ret == PLAYER_ERROR_NONE) {
3509                 ret_val = _player_get_param_value(ret_buf,
3510                                                                         MUSE_TYPE_STRING, "video_codec", (void *)video_codec,
3511                                                                         MUSE_TYPE_STRING, "audio_codec", (void *)audio_codec,
3512                                                                         INVALID_MUSE_TYPE_VALUE);
3513                 if (ret_val) {
3514                         if (pvideo_codec)
3515                                 *pvideo_codec = strndup(video_codec, MUSE_MSG_MAX_LENGTH);
3516                         if (paudio_codec)
3517                                 *paudio_codec = strndup(audio_codec, MUSE_MSG_MAX_LENGTH);
3518                 } else {
3519                         ret = PLAYER_ERROR_INVALID_OPERATION;
3520                 }
3521         }
3522         g_free(ret_buf);
3523         return ret;
3524 }
3525
3526 int player_get_audio_stream_info(player_h player, int *psample_rate, int *pchannel, int *pbit_rate)
3527 {
3528         int ret = PLAYER_ERROR_NONE;
3529         muse_player_api_e api = MUSE_PLAYER_API_GET_AUDIO_STREAM_INFO;
3530         player_cli_s *pc = (player_cli_s *)player;
3531         char *ret_buf = NULL;
3532         int sample_rate = 0;
3533         int channel = 0;
3534         int bit_rate = 0;
3535
3536         PLAYER_INSTANCE_CHECK(player);
3537         PLAYER_NULL_ARG_CHECK(psample_rate || pchannel || pbit_rate);
3538
3539         LOGD("ENTER");
3540
3541         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3542         if (ret == PLAYER_ERROR_NONE) {
3543                 bool ret_val = true;
3544                 ret_val = _player_get_param_value(ret_buf,
3545                                                                                 MUSE_TYPE_INT, "sample_rate", (void *)&sample_rate,
3546                                                                                 MUSE_TYPE_INT, "channel", (void *)&channel,
3547                                                                                 MUSE_TYPE_INT, "bit_rate", (void *)&bit_rate,
3548                                                                                 INVALID_MUSE_TYPE_VALUE);
3549                 if (ret_val) {
3550                         if (psample_rate)
3551                                 *psample_rate = sample_rate;
3552                         if (pchannel)
3553                                 *pchannel = channel;
3554                         if (pbit_rate)
3555                                 *pbit_rate = bit_rate;
3556                 } else {
3557                         ret = PLAYER_ERROR_INVALID_OPERATION;
3558                 }
3559         }
3560         g_free(ret_buf);
3561         return ret;
3562 }
3563
3564 int player_get_video_stream_info(player_h player, int *pfps, int *pbit_rate)
3565 {
3566         int ret = PLAYER_ERROR_NONE;
3567         muse_player_api_e api = MUSE_PLAYER_API_GET_VIDEO_STREAM_INFO;
3568         player_cli_s *pc = (player_cli_s *)player;
3569         char *ret_buf = NULL;
3570         int fps = 0;
3571         int bit_rate = 0;
3572
3573         PLAYER_INSTANCE_CHECK(player);
3574         PLAYER_NULL_ARG_CHECK(pfps || pbit_rate);
3575
3576         LOGD("ENTER");
3577
3578         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3579         if (ret == PLAYER_ERROR_NONE) {
3580                 bool ret_val = true;
3581                 ret_val = _player_get_param_value(ret_buf,
3582                                                                         MUSE_TYPE_INT, "fps", (void *)&fps,
3583                                                                         MUSE_TYPE_INT, "bit_rate", (void *)&bit_rate,
3584                                                                         INVALID_MUSE_TYPE_VALUE);
3585                 if (ret_val) {
3586                         if (pfps)
3587                                 *pfps = fps;
3588                         if (pbit_rate)
3589                                 *pbit_rate = bit_rate;
3590                 } else {
3591                         ret = PLAYER_ERROR_INVALID_OPERATION;
3592                 }
3593         }
3594         g_free(ret_buf);
3595         return ret;
3596 }
3597
3598 int player_get_video_size(player_h player, int *pwidth, int *pheight)
3599 {
3600         int ret = PLAYER_ERROR_NONE;
3601         muse_player_api_e api = MUSE_PLAYER_API_GET_VIDEO_SIZE;
3602         player_cli_s *pc = (player_cli_s *)player;
3603         char *ret_buf = NULL;
3604         int width = 0;
3605         int height = 0;
3606
3607         PLAYER_INSTANCE_CHECK(player);
3608         PLAYER_NULL_ARG_CHECK(pwidth && pheight);
3609
3610         LOGD("ENTER");
3611
3612         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3613         if (ret == PLAYER_ERROR_NONE) {
3614                 bool ret_val = true;
3615                 ret_val = _player_get_param_value(ret_buf,
3616                                                                         MUSE_TYPE_INT, "width", (void *)&width,
3617                                                                         MUSE_TYPE_INT, "height", (void *)&height,
3618                                                                         INVALID_MUSE_TYPE_VALUE);
3619                 if (ret_val) {
3620                         *pwidth = width;
3621                         *pheight = height;
3622                 } else {
3623                         ret = PLAYER_ERROR_INVALID_OPERATION;
3624                 }
3625         }
3626         g_free(ret_buf);
3627         return ret;
3628 }
3629
3630 int player_get_album_art(player_h player, void **palbum_art, int *psize)
3631 {
3632         int ret = PLAYER_ERROR_NONE;
3633         muse_player_api_e api = MUSE_PLAYER_API_GET_ALBUM_ART;
3634         player_cli_s *pc = (player_cli_s *)player;
3635         char *ret_buf = NULL;
3636         char *album_art;
3637         int size = 0;
3638         tbm_bo bo = NULL;
3639         tbm_bo_handle thandle;
3640         tbm_fd tfd = INVALID_DEFAULT_VALUE;
3641         int key = INVALID_DEFAULT_VALUE;
3642         void *jobj = NULL;
3643
3644         PLAYER_INSTANCE_CHECK(player);
3645         PLAYER_NULL_ARG_CHECK(palbum_art && psize);
3646
3647         LOGD("ENTER");
3648
3649         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3650         if (ret == PLAYER_ERROR_NONE) {
3651                 muse_core_msg_parse_err_e err = MUSE_MSG_PARSE_ERROR_NONE;
3652                 jobj = muse_core_msg_object_new(ret_buf, NULL, &err);
3653                 if (!jobj) {
3654                         LOGE("failed to get msg obj, err:%d", err);
3655                         ret = PLAYER_ERROR_INVALID_OPERATION;
3656                         goto EXIT;
3657                 }
3658
3659                 if (muse_core_msg_object_get_value("size", jobj, MUSE_TYPE_INT, &size) && (size > 0)) {
3660                         LOGD("size : %d", size);
3661                         if (!muse_core_msg_object_get_value("key", jobj, MUSE_TYPE_INT, &key)) {
3662                                 LOGE("failed to get key value");
3663                                 ret = PLAYER_ERROR_INVALID_OPERATION;
3664                                 goto EXIT;
3665                         }
3666
3667                         tfd = pc->cb_info->tfd;
3668                         if (tfd < 0) {
3669                                 LOGE("failed to get tbm fd value");
3670                                 ret = PLAYER_ERROR_INVALID_OPERATION;
3671                                 goto EXIT;
3672                         }
3673
3674                         bo = tbm_bo_import_fd(pc->cb_info->bufmgr, tfd);
3675                         if (bo == NULL) {
3676                                 LOGE("TBM get error : bo is NULL");
3677                                 ret = PLAYER_ERROR_INVALID_OPERATION;
3678                                 goto EXIT;
3679                         }
3680                         thandle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE | TBM_OPTION_READ);
3681                         if (thandle.ptr == NULL) {
3682                                 LOGE("TBM get error : handle pointer is NULL");
3683                                 ret = PLAYER_ERROR_INVALID_OPERATION;
3684                                 goto EXIT;
3685                         }
3686                         album_art = _get_mem(pc, size);
3687                         if (album_art) {
3688                                 memcpy(album_art, thandle.ptr, size);
3689                                 *palbum_art = album_art;
3690                         } else {
3691                                 LOGE("g_new failure");
3692                                 ret = PLAYER_ERROR_INVALID_OPERATION;
3693                         }
3694                         tbm_bo_unmap(bo);
3695                         *psize = size;
3696                 } else {
3697                         *palbum_art = NULL;
3698                         *psize = 0;
3699                 }
3700         }
3701
3702 EXIT:
3703         if (jobj)
3704                 muse_core_msg_object_free(jobj);
3705
3706         g_free(ret_buf);
3707
3708         PLAYER_CLOSE_FD(tfd);
3709
3710         if (CALLBACK_INFO(pc))
3711                 pc->cb_info->tfd = INVALID_DEFAULT_VALUE;
3712
3713         if (bo)
3714                 tbm_bo_unref(bo);
3715
3716         /* return buffer */
3717         if (key > INVALID_DEFAULT_VALUE && CALLBACK_INFO(pc)) {
3718                 LOGD("send msg to release buffer. key:%d", key);
3719                 PLAYER_SEND_MSG_ASYNC(MUSE_PLAYER_API_RETURN_BUFFER, MSG_FD(pc), ret, MUSE_TYPE_INT, "key", key);
3720         }
3721
3722         return ret;
3723 }
3724
3725 int player_audio_effect_get_equalizer_bands_count(player_h player, int *pcount)
3726 {
3727         int ret = PLAYER_ERROR_NONE;
3728         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_GET_EQUALIZER_BANDS_COUNT;
3729         player_cli_s *pc = (player_cli_s *)player;
3730         char *ret_buf = NULL;
3731         int count;
3732
3733         PLAYER_INSTANCE_CHECK(player);
3734         PLAYER_NULL_ARG_CHECK(pcount);
3735
3736         LOGD("ENTER");
3737
3738         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3739         if (ret == PLAYER_ERROR_NONE) {
3740                 player_msg_get(count, ret_buf);
3741                 *pcount = count;
3742         }
3743         g_free(ret_buf);
3744         return ret;
3745 }
3746
3747 int player_audio_effect_set_equalizer_all_bands(player_h player, int *band_levels, int length)
3748 {
3749         int ret = PLAYER_ERROR_NONE;
3750         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_SET_EQUALIZER_ALL_BANDS;
3751         player_cli_s *pc = (player_cli_s *)player;
3752         char *ret_buf = NULL;
3753
3754         PLAYER_INSTANCE_CHECK(player);
3755         PLAYER_NULL_ARG_CHECK(band_levels);
3756
3757         LOGD("ENTER");
3758
3759         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
3760                                         MUSE_TYPE_INT, "length", length,
3761                                         MUSE_TYPE_ARRAY, "band_levels", length, band_levels);
3762
3763         g_free(ret_buf);
3764         return ret;
3765
3766 }
3767
3768 int player_audio_effect_set_equalizer_band_level(player_h player, int index, int level)
3769 {
3770         int ret = PLAYER_ERROR_NONE;
3771         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_SET_EQUALIZER_BAND_LEVEL;
3772         player_cli_s *pc = (player_cli_s *)player;
3773         char *ret_buf = NULL;
3774
3775         PLAYER_INSTANCE_CHECK(player);
3776
3777         LOGD("ENTER");
3778
3779         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
3780                                         MUSE_TYPE_INT, "index", index,
3781                                         MUSE_TYPE_INT, "level", level);
3782
3783         g_free(ret_buf);
3784         return ret;
3785 }
3786
3787 int player_audio_effect_get_equalizer_band_level(player_h player, int index, int *plevel)
3788 {
3789         int ret = PLAYER_ERROR_NONE;
3790         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_GET_EQUALIZER_BAND_LEVEL;
3791         player_cli_s *pc = (player_cli_s *)player;
3792         char *ret_buf = NULL;
3793         int level;
3794
3795         PLAYER_INSTANCE_CHECK(player);
3796         PLAYER_NULL_ARG_CHECK(plevel);
3797
3798         LOGD("ENTER");
3799
3800         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "index", index);
3801         if (ret == PLAYER_ERROR_NONE) {
3802                 player_msg_get(level, ret_buf);
3803                 *plevel = level;
3804         }
3805         g_free(ret_buf);
3806         return ret;
3807 }
3808
3809 int player_audio_effect_get_equalizer_level_range(player_h player, int *pmin, int *pmax)
3810 {
3811         int ret = PLAYER_ERROR_NONE;
3812         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_GET_EQUALIZER_LEVEL_RANGE;
3813         player_cli_s *pc = (player_cli_s *)player;
3814         char *ret_buf = NULL;
3815         int min = 0, max = 0;
3816
3817         PLAYER_INSTANCE_CHECK(player);
3818         PLAYER_NULL_ARG_CHECK(pmin && pmax);
3819
3820         LOGD("ENTER");
3821
3822         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3823         if (ret == PLAYER_ERROR_NONE) {
3824                 bool ret_val = true;
3825                 ret_val = _player_get_param_value(ret_buf,
3826                                                                         MUSE_TYPE_INT, "min", (void *)&min,
3827                                                                         MUSE_TYPE_INT, "max", (void *)&max,
3828                                                                         INVALID_MUSE_TYPE_VALUE);
3829                 if (ret_val) {
3830                         *pmin = min;
3831                         *pmax = max;
3832                 } else {
3833                         ret = PLAYER_ERROR_INVALID_OPERATION;
3834                 }
3835         }
3836         g_free(ret_buf);
3837         return ret;
3838 }
3839
3840 int player_audio_effect_get_equalizer_band_frequency(player_h player, int index, int *pfrequency)
3841 {
3842         int ret = PLAYER_ERROR_NONE;
3843         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_GET_EQUALIZER_BAND_FREQUENCY;
3844         player_cli_s *pc = (player_cli_s *)player;
3845         char *ret_buf = NULL;
3846         int frequency;
3847
3848         PLAYER_INSTANCE_CHECK(player);
3849         PLAYER_NULL_ARG_CHECK(pfrequency);
3850
3851         LOGD("ENTER");
3852
3853         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "index", index);
3854         if (ret == PLAYER_ERROR_NONE) {
3855                 player_msg_get(frequency, ret_buf);
3856                 *pfrequency = frequency;
3857         }
3858         g_free(ret_buf);
3859         return ret;
3860 }
3861
3862 int player_audio_effect_get_equalizer_band_frequency_range(player_h player, int index, int *prange)
3863 {
3864         int ret = PLAYER_ERROR_NONE;
3865         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_GET_EQUALIZER_BAND_FREQUENCY_RANGE;
3866         player_cli_s *pc = (player_cli_s *)player;
3867         char *ret_buf = NULL;
3868         int range;
3869
3870         PLAYER_INSTANCE_CHECK(player);
3871         PLAYER_NULL_ARG_CHECK(prange);
3872
3873         LOGD("ENTER");
3874
3875         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "index", index);
3876         if (ret == PLAYER_ERROR_NONE) {
3877                 player_msg_get(range, ret_buf);
3878                 *prange = range;
3879         }
3880         g_free(ret_buf);
3881         return ret;
3882 }
3883
3884 int player_audio_effect_equalizer_clear(player_h player)
3885 {
3886         int ret = PLAYER_ERROR_NONE;
3887         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_EQUALIZER_CLEAR;
3888         player_cli_s *pc = (player_cli_s *)player;
3889         char *ret_buf = NULL;
3890
3891         PLAYER_INSTANCE_CHECK(player);
3892
3893         LOGD("ENTER");
3894
3895         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3896         g_free(ret_buf);
3897         return ret;
3898 }
3899
3900 int player_audio_effect_equalizer_is_available(player_h player, bool *pavailable)
3901 {
3902         int ret = PLAYER_ERROR_NONE;
3903         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_EFFECT_EQUALIZER_IS_AVAILABLE;
3904         player_cli_s *pc = (player_cli_s *)player;
3905         char *ret_buf = NULL;
3906         int available;
3907
3908         PLAYER_INSTANCE_CHECK(player);
3909         PLAYER_NULL_ARG_CHECK(pavailable);
3910
3911         LOGD("ENTER");
3912
3913         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3914         if (ret == PLAYER_ERROR_NONE) {
3915                 player_msg_get(available, ret_buf);
3916                 *pavailable = available;
3917         }
3918         g_free(ret_buf);
3919         return ret;
3920 }
3921
3922 int player_set_subtitle_path(player_h player, const char *path)
3923 {
3924         int ret = PLAYER_ERROR_NONE;
3925         muse_player_api_e api = MUSE_PLAYER_API_SET_SUBTITLE_PATH;
3926         player_cli_s *pc = (player_cli_s *)player;
3927         char *ret_buf = NULL;
3928         char subtitle_path[MAX_URL_LEN] = {0, };
3929
3930         PLAYER_INSTANCE_CHECK(player);
3931
3932         LOGD("ENTER");
3933
3934         if (path && _player_get_valid_path(path, subtitle_path) != PLAYER_ERROR_NONE)
3935                 return PLAYER_ERROR_INVALID_PARAMETER;
3936
3937         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_STRING, "subtitle_path", (const char *)subtitle_path);
3938         g_free(ret_buf);
3939         return ret;
3940 }
3941
3942 int player_set_subtitle_position_offset(player_h player, int milliseconds)
3943 {
3944         int ret = PLAYER_ERROR_NONE;
3945         muse_player_api_e api = MUSE_PLAYER_API_SET_SUBTITLE_POSITION_OFFSET;
3946         player_cli_s *pc = (player_cli_s *)player;
3947         char *ret_buf = NULL;
3948
3949         PLAYER_INSTANCE_CHECK(player);
3950
3951         LOGD("ENTER");
3952
3953         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "milliseconds", milliseconds);
3954
3955         g_free(ret_buf);
3956         return ret;
3957 }
3958
3959 int player_capture_video(player_h player, player_video_captured_cb callback, void *user_data)
3960 {
3961         int ret = PLAYER_ERROR_NONE;
3962         muse_player_api_e api = MUSE_PLAYER_API_CAPTURE_VIDEO;
3963         player_cli_s *pc = (player_cli_s *)player;
3964         char *ret_buf = NULL;
3965
3966         PLAYER_INSTANCE_CHECK(player);
3967         PLAYER_NULL_ARG_CHECK(callback);
3968
3969         LOGD("ENTER");
3970         if (pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_CAPTURE]) {
3971                 LOGE("PLAYER_ERROR_VIDEO_CAPTURE_FAILED (0x%08x) : capturing...", PLAYER_ERROR_VIDEO_CAPTURE_FAILED);
3972                 return PLAYER_ERROR_VIDEO_CAPTURE_FAILED;
3973         } else {
3974                 LOGI("Event type : %d ", MUSE_PLAYER_EVENT_TYPE_CAPTURE);
3975                 pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_CAPTURE] = callback;
3976                 pc->cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_CAPTURE] = user_data;
3977         }
3978
3979         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
3980
3981         if (ret != PLAYER_ERROR_NONE)
3982                 set_null_user_cb(pc->cb_info, MUSE_PLAYER_EVENT_TYPE_CAPTURE);
3983
3984         g_free(ret_buf);
3985         return ret;
3986 }
3987
3988 int player_set_streaming_cookie(player_h player, const char *cookie, int size)
3989 {
3990         int ret = PLAYER_ERROR_NONE;
3991         muse_player_api_e api = MUSE_PLAYER_API_SET_STREAMING_COOKIE;
3992         player_cli_s *pc = (player_cli_s *)player;
3993         char *ret_buf = NULL;
3994
3995         PLAYER_INSTANCE_CHECK(player);
3996         PLAYER_NULL_ARG_CHECK(cookie);
3997         PLAYER_CHECK_CONDITION(size >= 0, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
3998
3999         LOGD("ENTER");
4000
4001         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4002                                         MUSE_TYPE_STRING, "cookie", cookie,
4003                                         MUSE_TYPE_INT, "size", size);
4004         g_free(ret_buf);
4005         return ret;
4006 }
4007
4008 int player_set_streaming_user_agent(player_h player, const char *user_agent, int size)
4009 {
4010         int ret = PLAYER_ERROR_NONE;
4011         muse_player_api_e api = MUSE_PLAYER_API_SET_STREAMING_USER_AGENT;
4012         player_cli_s *pc = (player_cli_s *)player;
4013         char *ret_buf = NULL;
4014
4015         PLAYER_INSTANCE_CHECK(player);
4016         PLAYER_NULL_ARG_CHECK(user_agent);
4017         PLAYER_CHECK_CONDITION(size >= 0, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
4018
4019         LOGD("ENTER");
4020
4021         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4022                                         MUSE_TYPE_STRING, "user_agent", user_agent,
4023                                         MUSE_TYPE_INT, "size", size);
4024         g_free(ret_buf);
4025         return ret;
4026 }
4027
4028 int player_get_streaming_download_progress(player_h player, int *start, int *end)
4029 {
4030         int ret = PLAYER_ERROR_NONE;
4031         muse_player_api_e api = MUSE_PLAYER_API_GET_STREAMING_DOWNLOAD_PROGRESS;
4032         player_cli_s *pc = (player_cli_s *)player;
4033         char *ret_buf = NULL;
4034         int start_pos = 0, end_pos = 0;
4035
4036         PLAYER_INSTANCE_CHECK(player);
4037         PLAYER_NULL_ARG_CHECK(start && end);
4038
4039         LOGD("ENTER");
4040
4041         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
4042         if (ret == PLAYER_ERROR_NONE) {
4043                 bool ret_val = true;
4044                 ret_val = _player_get_param_value(ret_buf,
4045                                                                         MUSE_TYPE_INT, "start_pos", (void *)&start_pos,
4046                                                                         MUSE_TYPE_INT, "end_pos", (void *)&end_pos,
4047                                                                         INVALID_MUSE_TYPE_VALUE);
4048                 if (ret_val) {
4049                         *start = start_pos;
4050                         *end = end_pos;
4051                 } else {
4052                         ret = PLAYER_ERROR_INVALID_OPERATION;
4053                 }
4054         }
4055         g_free(ret_buf);
4056         return ret;
4057 }
4058
4059 int player_set_completed_cb(player_h player, player_completed_cb callback, void *user_data)
4060 {
4061         return __set_callback(MUSE_PLAYER_EVENT_TYPE_COMPLETE, player, callback, user_data);
4062 }
4063
4064 static void __retrieve_buffer_cb(void *user_data)
4065 {
4066         player_cli_s *player = (player_cli_s *)user_data;
4067         int ret = PLAYER_ERROR_NONE;
4068         bool gapless = false;
4069
4070         ret = player_is_gapless((player_h)player, &gapless);
4071         if (ret != PLAYER_ERROR_NONE) {
4072                 LOGW("player_is_gapless is failed");
4073                 return;
4074         }
4075
4076         ret = mm_display_interface_evas_flush(DP_INTERFACE(player), gapless);
4077
4078         LOGW("flush all packet : 0x%x [gapless %d]", ret, gapless);
4079 }
4080
4081 static int __player_set_retrieve_buffer_cb(player_h player, player_retrieve_buffer_cb callback, void *user_data)
4082 {
4083         return __set_callback(MUSE_PLAYER_EVENT_TYPE_RETURN_BUFFER, player, callback, user_data);
4084 }
4085
4086 static int __player_unset_retrieve_buffer_cb(player_h player)
4087 {
4088         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_RETURN_BUFFER, player);
4089 }
4090
4091 int player_unset_completed_cb(player_h player)
4092 {
4093         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_COMPLETE, player);
4094 }
4095
4096 int player_set_interrupted_cb(player_h player, player_interrupted_cb callback, void *user_data)
4097 {
4098         return __set_callback(MUSE_PLAYER_EVENT_TYPE_INTERRUPT, player, callback, user_data);
4099 }
4100
4101 int player_unset_interrupted_cb(player_h player)
4102 {
4103         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_INTERRUPT, player);
4104 }
4105
4106 int player_set_error_cb(player_h player, player_error_cb callback, void *user_data)
4107 {
4108         return __set_callback(MUSE_PLAYER_EVENT_TYPE_ERROR, player, callback, user_data);
4109 }
4110
4111 int player_unset_error_cb(player_h player)
4112 {
4113         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_ERROR, player);
4114 }
4115
4116 int player_set_buffering_cb(player_h player, player_buffering_cb callback, void *user_data)
4117 {
4118         return __set_callback(MUSE_PLAYER_EVENT_TYPE_BUFFERING, player, callback, user_data);
4119 }
4120
4121 int player_unset_buffering_cb(player_h player)
4122 {
4123         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_BUFFERING, player);
4124 }
4125
4126 int player_set_subtitle_updated_cb(player_h player, player_subtitle_updated_cb callback, void *user_data)
4127 {
4128         return __set_callback(MUSE_PLAYER_EVENT_TYPE_SUBTITLE, player, callback, user_data);
4129 }
4130
4131 int player_unset_subtitle_updated_cb(player_h player)
4132 {
4133         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_SUBTITLE, player);
4134 }
4135
4136 int player_set_media_packet_video_frame_decoded_cb(player_h player, player_media_packet_video_decoded_cb callback, void *user_data)
4137 {
4138         return __set_callback(MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME, player, callback, user_data);
4139 }
4140
4141 int player_unset_media_packet_video_frame_decoded_cb(player_h player)
4142 {
4143         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_VIDEO_FRAME, player);
4144 }
4145
4146 int player_set_media_packet_audio_frame_decoded_cb(player_h player, media_format_h format,
4147                 player_audio_extract_option_e opt, player_media_packet_audio_decoded_cb callback, void *user_data)
4148 {
4149         int ret = PLAYER_ERROR_NONE;
4150         player_cli_s *pc = (player_cli_s *)player;
4151         muse_player_api_e api = MUSE_PLAYER_API_SET_MEDIA_PACKET_AUDIO_FRAME_DECODED_CB;
4152         char *ret_buf = NULL;
4153         media_format_mimetype_e mimetype = MEDIA_FORMAT_MAX;
4154         int channel = 0;
4155         int samplerate = 0;
4156
4157         PLAYER_INSTANCE_CHECK(player);
4158         PLAYER_NULL_ARG_CHECK(callback);
4159         PLAYER_RANGE_ARG_CHECK(opt, PLAYER_AUDIO_EXTRACT_DEFAULT, PLAYER_AUDIO_EXTRACT_NO_SYNC_AND_DEINTERLEAVE);
4160
4161         LOGD("ENTER");
4162
4163         if (format) {
4164                 media_format_ref(format);
4165                 if (media_format_get_audio_info(format, &mimetype, &channel, &samplerate, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE) {
4166                         LOGE("failed to get audio info from media format.");
4167                         media_format_unref(format);
4168                         return PLAYER_ERROR_INVALID_PARAMETER;
4169                 }
4170                 media_format_unref(format);
4171
4172                 if (mimetype < MEDIA_FORMAT_PCM || mimetype > MEDIA_FORMAT_PCM_U32BE) {
4173                         LOGW("Not supported audio format type : 0x%X", mimetype);
4174                         return PLAYER_ERROR_INVALID_PARAMETER;
4175                 }
4176         }
4177
4178         LOGD("pcm spec : 0x%X, %d, %d", mimetype, channel, samplerate);
4179
4180         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4181                                         MUSE_TYPE_INT, "opt", opt,
4182                                         MUSE_TYPE_INT, "mimetype", mimetype,
4183                                         MUSE_TYPE_INT, "channel", channel,
4184                                         MUSE_TYPE_INT, "samplerate", samplerate);
4185
4186         if (ret == PLAYER_ERROR_NONE) {
4187                 pc->cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME] = callback;
4188                 pc->cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME] = user_data;
4189                 LOGI("Event type : %d ", MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME);
4190         }
4191
4192         g_free(ret_buf);
4193         return ret;
4194 }
4195
4196 int player_unset_media_packet_audio_frame_decoded_cb(player_h player)
4197 {
4198         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_MEDIA_PACKET_AUDIO_FRAME, player);
4199 }
4200
4201 int player_set_video_stream_changed_cb(player_h player, player_video_stream_changed_cb callback, void *user_data)
4202 {
4203         return __set_callback(MUSE_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED, player, callback, user_data);
4204 }
4205
4206 int player_unset_video_stream_changed_cb(player_h player)
4207 {
4208         return __unset_callback(MUSE_PLAYER_EVENT_TYPE_VIDEO_STREAM_CHANGED, player);
4209 }
4210
4211 int player_set_media_stream_buffer_status_cb(player_h player,
4212                 player_stream_type_e stream_type, player_media_stream_buffer_status_cb callback, void *user_data)
4213 {
4214         muse_player_event_e type;
4215
4216         PLAYER_INSTANCE_CHECK(player);
4217         PLAYER_NULL_ARG_CHECK(callback);
4218
4219         LOGD("ENTER");
4220
4221         if (stream_type == PLAYER_STREAM_TYPE_VIDEO) {
4222                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS;
4223         } else if (stream_type == PLAYER_STREAM_TYPE_AUDIO) {
4224                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS;
4225         } else {
4226                 LOGE("PLAYER_ERROR_INVALID_PARAMETER(type : %d)", stream_type);
4227                 return PLAYER_ERROR_INVALID_PARAMETER;
4228         }
4229
4230         return __set_callback(type, player, callback, user_data);
4231 }
4232
4233 int player_unset_media_stream_buffer_status_cb(player_h player, player_stream_type_e stream_type)
4234 {
4235         muse_player_event_e type;
4236
4237         PLAYER_INSTANCE_CHECK(player);
4238
4239         LOGD("ENTER");
4240
4241         if (stream_type == PLAYER_STREAM_TYPE_VIDEO) {
4242                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS;
4243         } else if (stream_type == PLAYER_STREAM_TYPE_AUDIO) {
4244                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS;
4245         } else {
4246                 LOGE("PLAYER_ERROR_INVALID_PARAMETER(type : %d)", stream_type);
4247                 return PLAYER_ERROR_INVALID_PARAMETER;
4248         }
4249
4250         return __unset_callback(type, player);
4251 }
4252
4253 int player_set_media_stream_seek_cb(player_h player,
4254                 player_stream_type_e stream_type, player_media_stream_seek_cb callback, void *user_data)
4255 {
4256         muse_player_event_e type;
4257
4258         PLAYER_INSTANCE_CHECK(player);
4259         PLAYER_NULL_ARG_CHECK(callback);
4260
4261         LOGD("ENTER");
4262
4263         if (stream_type == PLAYER_STREAM_TYPE_VIDEO) {
4264                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK;
4265         } else if (stream_type == PLAYER_STREAM_TYPE_AUDIO) {
4266                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK;
4267         } else {
4268                 LOGE("PLAYER_ERROR_INVALID_PARAMETER(type : %d)", stream_type);
4269                 return PLAYER_ERROR_INVALID_PARAMETER;
4270         }
4271
4272         return __set_callback(type, player, callback, user_data);
4273 }
4274
4275 int player_unset_media_stream_seek_cb(player_h player, player_stream_type_e stream_type)
4276 {
4277         muse_player_event_e type;
4278
4279         PLAYER_INSTANCE_CHECK(player);
4280
4281         LOGD("ENTER");
4282
4283         if (stream_type == PLAYER_STREAM_TYPE_VIDEO) {
4284                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_SEEK;
4285         } else if (stream_type == PLAYER_STREAM_TYPE_AUDIO) {
4286                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_SEEK;
4287         } else {
4288                 LOGE("PLAYER_ERROR_INVALID_PARAMETER(type : %d)", stream_type);
4289                 return PLAYER_ERROR_INVALID_PARAMETER;
4290         }
4291
4292         return __unset_callback(type, player);
4293 }
4294
4295 /* TODO Implement raw data socket channel */
4296 int player_push_media_stream(player_h player, media_packet_h packet)
4297 {
4298         int ret = PLAYER_ERROR_NONE;
4299         int packet_ret = MEDIA_PACKET_ERROR_NONE;
4300         player_cli_s *pc = (player_cli_s *)player;
4301         muse_player_api_e api = MUSE_PLAYER_API_PUSH_MEDIA_STREAM;
4302         char *ret_buf = NULL;
4303         player_push_media_msg_type push_media;
4304         char *push_media_msg = (char *)&push_media;
4305         int msg_size = sizeof(player_push_media_msg_type);
4306         int buf_size = 0;
4307 #ifdef __UN_USED
4308         tbm_bo bo = NULL;
4309         tbm_bo_handle thandle;
4310         tbm_fd tfd = INVALID_DEFAULT_VALUE;
4311 #endif
4312         char *buf;
4313         media_format_h format;
4314         bool is_video;
4315         bool is_audio;
4316         bool is_eos;
4317         int arr_msg_len = 0;
4318         char *codec_data = NULL;
4319         unsigned int codec_data_size = 0;
4320
4321         PLAYER_INSTANCE_CHECK(player);
4322         PLAYER_NULL_ARG_CHECK(packet);
4323
4324         LOGD("ENTER");
4325
4326         if (media_packet_get_buffer_data_ptr(packet, (void **)&buf) != MEDIA_PACKET_ERROR_NONE) {
4327                 LOGE("failed to get buffer data ptr");
4328                 return PLAYER_ERROR_INVALID_OPERATION;
4329         }
4330
4331         if (media_packet_get_buffer_size(packet, &push_media.size) != MEDIA_PACKET_ERROR_NONE) {
4332                 LOGE("failed to get buffer size");
4333                 return PLAYER_ERROR_INVALID_OPERATION;
4334         }
4335
4336         if (media_packet_get_pts(packet, &push_media.pts) != MEDIA_PACKET_ERROR_NONE) {
4337                 LOGE("failed to get buffer pts");
4338                 return PLAYER_ERROR_INVALID_OPERATION;
4339         }
4340
4341         if (media_packet_get_format(packet, &format) != MEDIA_PACKET_ERROR_NONE) {   /* format ref count is increased */
4342                 LOGE("failed to get media format");
4343                 return PLAYER_ERROR_INVALID_OPERATION;
4344         }
4345
4346         packet_ret = media_packet_get_flags(packet, &push_media.flags);
4347         packet_ret |= media_packet_is_video(packet, &is_video);
4348         packet_ret |= media_packet_is_audio(packet, &is_audio);
4349         packet_ret |= media_packet_is_end_of_stream(packet, &is_eos);
4350         if (is_video)
4351                 packet_ret |= media_format_get_video_info(format, &push_media.mimetype,
4352                                                         &push_media.width, &push_media.height, NULL, NULL);
4353         else if (is_audio)
4354                 packet_ret |= media_format_get_audio_info(format, &push_media.mimetype,
4355                                                         &push_media.channels, &push_media.samplerate, NULL, NULL);
4356
4357         media_format_unref(format);
4358
4359         if (packet_ret != MEDIA_PACKET_ERROR_NONE) {
4360                 LOGE("failed to get media packet info");
4361                 return PLAYER_ERROR_INVALID_OPERATION;
4362         }
4363
4364         if (media_packet_get_codec_data(packet, (void **)&codec_data, &codec_data_size) == MEDIA_PACKET_ERROR_NONE) {
4365                 if (codec_data_size > 0 && codec_data_size <= sizeof(push_media.codec_data))
4366                         memcpy(push_media.codec_data, codec_data, codec_data_size);
4367         }
4368
4369         push_media.codec_data_size = codec_data_size;
4370         push_media.buf_type = PUSH_MEDIA_BUF_TYPE_RAW;
4371
4372 #ifdef __UN_USED
4373         int arr_buf_len = 0;
4374
4375         if (push_media.buf_type == PUSH_MEDIA_BUF_TYPE_TBM) {
4376                 bo = tbm_bo_alloc(pc->cb_info->bufmgr, push_media.size, TBM_BO_DEFAULT);
4377                 if (bo == NULL) {
4378                         LOGE("TBM get error : bo is NULL");
4379                         return PLAYER_ERROR_INVALID_OPERATION;
4380                 }
4381                 thandle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
4382                 if (thandle.ptr == NULL) {
4383                         LOGE("TBM get error : handle pointer is NULL");
4384                         ret = PLAYER_ERROR_INVALID_OPERATION;
4385                         goto ERROR;
4386                 }
4387                 memcpy(thandle.ptr, buf, push_media.size);
4388                 tbm_bo_unmap(bo);
4389
4390                 tfd = tbm_bo_export_fd(bo);
4391                 if (tfd < 0) {
4392                         LOGE("tbm_bo_export_fd err 0x%x", tfd);
4393                         ret = PLAYER_ERROR_INVALID_OPERATION;
4394                         goto ERROR;
4395                 }
4396
4397                 arr_msg_len = (msg_size / sizeof(int) + (msg_size % sizeof(int) ? 1 : 0));
4398                 PLAYER_SEND_MSG_WITH_TFD(api, pc, tfd, ret_buf, ret,
4399                                                                 MUSE_TYPE_ARRAY, "push_media_msg", arr_msg_len, (int *)push_media_msg);
4400
4401         } else if (push_media.buf_type == PUSH_MEDIA_BUF_TYPE_MSG) {
4402                 buf_size = (int)push_media.size;
4403
4404                 arr_msg_len = (msg_size / sizeof(int) + (msg_size % sizeof(int) ? 1 : 0));
4405                 arr_buf_len = (buf_size / sizeof(int) + (buf_size % sizeof(int) ? 1 : 0));
4406                 PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4407                                                 MUSE_TYPE_ARRAY, "push_media_msg", arr_msg_len, (int *)push_media_msg,
4408                                                 MUSE_TYPE_ARRAY, "buf", arr_buf_len, (int *)buf);
4409
4410         } else
4411 #endif
4412         if (push_media.buf_type == PUSH_MEDIA_BUF_TYPE_RAW) {
4413                 buf_size = (int)push_media.size;
4414                 if ((muse_client_ipc_push_data(pc->cb_info->data_fd, buf, buf_size, push_media.pts) < 0) && (!is_eos)) {
4415                         LOGE("failed to send data");
4416                         return PLAYER_ERROR_INVALID_OPERATION;
4417                 }
4418
4419                 arr_msg_len = (msg_size / sizeof(int) + (msg_size % sizeof(int) ? 1 : 0));
4420                 PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4421                                                 MUSE_TYPE_ARRAY, "push_media_msg", arr_msg_len, (int *)push_media_msg);
4422         }
4423
4424         LOGD("ret_buf %s", ret_buf);
4425
4426 #ifdef __UN_USED
4427 ERROR:
4428
4429         PLAYER_CLOSE_FD(tfd);
4430
4431         if (push_media.buf_type == PUSH_MEDIA_BUF_TYPE_TBM)
4432                 tbm_bo_unref(bo);
4433 #endif
4434
4435         g_free(ret_buf);
4436         return ret;
4437 }
4438
4439 int player_foreach_media_stream_supported_format(player_h player, player_supported_media_format_cb callback, void *user_data)
4440 {
4441         int ret = PLAYER_ERROR_NONE;
4442         player_cli_s *pc = (player_cli_s *)player;
4443         muse_player_api_e api = MUSE_PLAYER_API_GET_MEDIA_STREAM_SUPPORTED_FORMAT;
4444         char *ret_buf = NULL;
4445         int format_info[MAX_SUPPORTED_MEDIA_FORMAT] = {0,};
4446         int len = 0, idx = 0;
4447
4448         PLAYER_INSTANCE_CHECK(player);
4449         PLAYER_NULL_ARG_CHECK(callback);
4450
4451         LOGD("ENTER");
4452
4453         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
4454
4455         player_msg_get_type(len, ret_buf, INT);
4456         player_msg_get_array(format_info, ret_buf);
4457
4458         LOGD("num of format %d", len);
4459         for (idx = 0 ; idx < len ; idx++) {
4460                 if (!callback(format_info[idx], user_data)) {
4461                         LOGW("stop foreach callback");
4462                         break;
4463                 }
4464         }
4465
4466         LOGD("LEAVE 0x%X", ret);
4467         g_free(ret_buf);
4468         return ret;
4469 }
4470
4471 int player_set_media_stream_info(player_h player, player_stream_type_e type, media_format_h format)
4472 {
4473         g_return_val_if_fail(format, PLAYER_ERROR_INVALID_OPERATION);
4474         int ret = PLAYER_ERROR_NONE;
4475         player_cli_s *pc = (player_cli_s *)player;
4476         muse_player_api_e api = MUSE_PLAYER_API_SET_MEDIA_STREAM_INFO;
4477         char *ret_buf = NULL;
4478         media_format_mimetype_e mimetype;
4479         int width = 0;
4480         int height = 0;
4481         int avg_bps = 0;
4482         int max_bps = 0;
4483         int channel = 0;
4484         int samplerate = 0;
4485         int bit = 0;
4486         int frame_rate = 0;
4487
4488         PLAYER_INSTANCE_CHECK(player);
4489
4490         LOGD("ENTER");
4491
4492         media_format_ref(format);
4493         if (type == PLAYER_STREAM_TYPE_VIDEO) {
4494                 if (media_format_get_video_info(format, &mimetype, &width, &height, &avg_bps, &max_bps) != MEDIA_FORMAT_ERROR_NONE ||
4495                         media_format_get_video_frame_rate(format, &frame_rate) != MEDIA_FORMAT_ERROR_NONE) {
4496                         LOGE("failed to get video info from format.");
4497                         return PLAYER_ERROR_INVALID_PARAMETER;
4498                 }
4499
4500                 PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4501                                                 MUSE_TYPE_INT, "type", type,
4502                                                 MUSE_TYPE_INT, "mimetype", mimetype,
4503                                                 MUSE_TYPE_INT, "width", width,
4504                                                 MUSE_TYPE_INT, "height", height,
4505                                                 MUSE_TYPE_INT, "avg_bps", avg_bps,
4506                                                 MUSE_TYPE_INT, "max_bps", max_bps,
4507                                                 MUSE_TYPE_INT, "frame_rate", frame_rate);
4508
4509         } else if (type == PLAYER_STREAM_TYPE_AUDIO) {
4510                 if (media_format_get_audio_info(format, &mimetype, &channel, &samplerate, &bit, &avg_bps) != MEDIA_FORMAT_ERROR_NONE) {
4511                         LOGE("failed to get audio info from format.");
4512                         return PLAYER_ERROR_INVALID_PARAMETER;
4513                 }
4514
4515                 PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4516                                                 MUSE_TYPE_INT, "type", type,
4517                                                 MUSE_TYPE_INT, "mimetype", mimetype,
4518                                                 MUSE_TYPE_INT, "channel", channel,
4519                                                 MUSE_TYPE_INT, "samplerate", samplerate,
4520                                                 MUSE_TYPE_INT, "avg_bps", avg_bps,
4521                                                 MUSE_TYPE_INT, "bit", bit);
4522
4523         }
4524         media_format_unref(format);
4525         pc->push_media_stream = TRUE;
4526
4527         g_free(ret_buf);
4528         return ret;
4529 }
4530
4531 int player_set_media_stream_buffer_max_size(player_h player, player_stream_type_e type, unsigned long long max_size)
4532 {
4533         int ret = PLAYER_ERROR_NONE;
4534         player_cli_s *pc = (player_cli_s *)player;
4535         muse_player_api_e api = MUSE_PLAYER_API_SET_MEDIA_STREAM_BUFFER_MAX_SIZE;
4536         char *ret_buf = NULL;
4537
4538         PLAYER_INSTANCE_CHECK(player);
4539         PLAYER_RANGE_ARG_CHECK(type, PLAYER_STREAM_TYPE_AUDIO, PLAYER_STREAM_TYPE_VIDEO);
4540         PLAYER_CHECK_CONDITION(max_size > 0, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
4541
4542         LOGD("ENTER");
4543
4544         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4545                                         MUSE_TYPE_INT, "type", type,
4546                                         MUSE_TYPE_INT64, "max_size", (INT64)max_size);
4547
4548         g_free(ret_buf);
4549         return ret;
4550 }
4551
4552 int player_get_media_stream_buffer_max_size(player_h player, player_stream_type_e type, unsigned long long *pmax_size)
4553 {
4554         int ret = PLAYER_ERROR_NONE;
4555         player_cli_s *pc = (player_cli_s *)player;
4556         muse_player_api_e api = MUSE_PLAYER_API_GET_MEDIA_STREAM_BUFFER_MAX_SIZE;
4557         char *ret_buf = NULL;
4558         unsigned long long max_size;
4559
4560         PLAYER_INSTANCE_CHECK(player);
4561         PLAYER_NULL_ARG_CHECK(pmax_size);
4562         PLAYER_RANGE_ARG_CHECK(type, PLAYER_STREAM_TYPE_AUDIO, PLAYER_STREAM_TYPE_VIDEO);
4563
4564         LOGD("ENTER");
4565
4566         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "type", type);
4567         if (ret == PLAYER_ERROR_NONE) {
4568                 player_msg_get_type(max_size, ret_buf, INT64);
4569                 *pmax_size = max_size;
4570         }
4571         g_free(ret_buf);
4572         return ret;
4573 }
4574
4575 int player_set_media_stream_buffer_min_threshold(player_h player, player_stream_type_e type, unsigned int percent)
4576 {
4577         int ret = PLAYER_ERROR_NONE;
4578         player_cli_s *pc = (player_cli_s *)player;
4579         muse_player_api_e api = MUSE_PLAYER_API_SET_MEDIA_STREAM_BUFFER_MIN_THRESHOLD;
4580         char *ret_buf = NULL;
4581
4582         PLAYER_INSTANCE_CHECK(player);
4583         PLAYER_RANGE_ARG_CHECK(type, PLAYER_STREAM_TYPE_DEFAULT, PLAYER_STREAM_TYPE_TEXT);
4584
4585         LOGD("ENTER");
4586
4587         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4588                                         MUSE_TYPE_INT, "type", type,
4589                                         MUSE_TYPE_INT, "percent", (int)percent);
4590
4591         g_free(ret_buf);
4592         return ret;
4593 }
4594
4595 int player_get_media_stream_buffer_min_threshold(player_h player, player_stream_type_e type, unsigned int *ppercent)
4596 {
4597         int ret = PLAYER_ERROR_NONE;
4598         player_cli_s *pc = (player_cli_s *)player;
4599         muse_player_api_e api = MUSE_PLAYER_API_GET_MEDIA_STREAM_BUFFER_MIN_THRESHOLD;
4600         char *ret_buf = NULL;
4601         unsigned int percent;
4602
4603         PLAYER_INSTANCE_CHECK(player);
4604         PLAYER_NULL_ARG_CHECK(ppercent);
4605
4606         LOGD("ENTER");
4607
4608         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "type", type);
4609         if (ret == PLAYER_ERROR_NONE) {
4610                 player_msg_get(percent, ret_buf);
4611                 *ppercent = percent;
4612         }
4613
4614         g_free(ret_buf);
4615         return ret;
4616 }
4617
4618 int player_get_track_count(player_h player, player_stream_type_e type, int *pcount)
4619 {
4620         int ret = PLAYER_ERROR_NONE;
4621         player_cli_s *pc = (player_cli_s *)player;
4622         muse_player_api_e api = MUSE_PLAYER_API_GET_TRACK_COUNT;
4623         char *ret_buf = NULL;
4624         int count;
4625
4626         PLAYER_INSTANCE_CHECK(player);
4627         PLAYER_NULL_ARG_CHECK(pcount);
4628
4629         LOGD("ENTER");
4630
4631         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "type", type);
4632         if (ret == PLAYER_ERROR_NONE) {
4633                 player_msg_get(count, ret_buf);
4634                 *pcount = count;
4635         }
4636
4637         g_free(ret_buf);
4638         return ret;
4639 }
4640
4641 int player_get_current_track(player_h player, player_stream_type_e type, int *pindex)
4642 {
4643         int ret = PLAYER_ERROR_NONE;
4644         player_cli_s *pc = (player_cli_s *)player;
4645         muse_player_api_e api = MUSE_PLAYER_API_GET_CURRENT_TRACK;
4646         char *ret_buf = NULL;
4647         int index;
4648
4649         PLAYER_INSTANCE_CHECK(player);
4650         PLAYER_NULL_ARG_CHECK(pindex);
4651
4652         LOGD("ENTER");
4653
4654         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "type", type);
4655         if (ret == PLAYER_ERROR_NONE) {
4656                 player_msg_get(index, ret_buf);
4657                 *pindex = index;
4658         }
4659
4660         g_free(ret_buf);
4661         return ret;
4662 }
4663
4664 int player_select_track(player_h player, player_stream_type_e type, int index)
4665 {
4666         int ret = PLAYER_ERROR_NONE;
4667         player_cli_s *pc = (player_cli_s *)player;
4668         muse_player_api_e api = MUSE_PLAYER_API_SELECT_TRACK;
4669         char *ret_buf = NULL;
4670
4671         PLAYER_INSTANCE_CHECK(player);
4672
4673         LOGD("ENTER");
4674
4675         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "type", type, MUSE_TYPE_INT, "index", index);
4676
4677         g_free(ret_buf);
4678         return ret;
4679 }
4680
4681 int player_get_track_language_code(player_h player, player_stream_type_e type, int index, char **pcode)
4682 {
4683         int ret = PLAYER_ERROR_NONE;
4684         player_cli_s *pc = (player_cli_s *)player;
4685         muse_player_api_e api = MUSE_PLAYER_API_GET_TRACK_LANGUAGE_CODE;
4686         char *ret_buf = NULL;
4687         char code[MUSE_MSG_MAX_LENGTH] = { 0, };
4688         int code_len = 0;
4689
4690         PLAYER_INSTANCE_CHECK(player);
4691         PLAYER_NULL_ARG_CHECK(pcode);
4692
4693         LOGD("ENTER");
4694
4695         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "type", type, MUSE_TYPE_INT, "index", index);
4696         if (ret == PLAYER_ERROR_NONE) {
4697                 bool recv_ret = true;
4698                 recv_ret = _player_get_param_value(ret_buf,
4699                                                                                 MUSE_TYPE_INT, "code_len", (void *)&code_len,
4700                                                                                 MUSE_TYPE_STRING, "code", (void *)code,
4701                                                                                 INVALID_MUSE_TYPE_VALUE);
4702                 if (recv_ret)
4703                         *pcode = strndup(code, code_len);
4704                 else
4705                         ret = PLAYER_ERROR_INVALID_OPERATION;
4706         }
4707         g_free(ret_buf);
4708         return ret;
4709 }
4710
4711 int player_foreach_adaptive_variant(player_h player, player_adaptive_variant_cb callback, void *user_data)
4712 {
4713         int ret = PLAYER_ERROR_NONE;
4714         player_cli_s *pc = (player_cli_s *)player;
4715         muse_player_api_e api = MUSE_PLAYER_API_GET_ADAPTIVE_VARIANT_INFO;
4716         char *ret_buf = NULL;
4717         char var_info[MUSE_MSG_MAX_LENGTH] = { 0, };
4718         int idx = 0, num = 0;
4719         int bandwidth = 0, width = 0, height = 0;
4720         char *token = NULL;
4721         char *ptr = NULL;
4722
4723         PLAYER_INSTANCE_CHECK(player);
4724         PLAYER_NULL_ARG_CHECK(callback);
4725
4726         LOGD("ENTER");
4727
4728         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
4729         if (ret == PLAYER_ERROR_NONE) {
4730                 player_msg_get_type(num, ret_buf, INT);
4731                 if (num > 0)
4732                         player_msg_get_string(var_info, ret_buf);
4733                 else
4734                         LOGW("There is no stream variant info.");
4735         }
4736
4737         for (idx = 0 ; idx < num ; idx++) {
4738                 bandwidth = width = height = 0;
4739
4740                 token = strtok_r((ptr != NULL) ? (NULL) : (var_info), ",", &ptr);
4741                 if (!token) break;
4742                 bandwidth = atoi(token);
4743
4744                 token = strtok_r(NULL, ",", &ptr);
4745                 if (!token) break;
4746                 width = atoi(token);
4747
4748                 token = strtok_r(NULL, ",", &ptr);
4749                 if (!token) break;
4750                 height = atoi(token);
4751
4752                 callback(bandwidth, width, height, user_data);
4753         }
4754
4755         LOGD("LEAVE 0x%X", ret);
4756         g_free(ret_buf);
4757         return ret;
4758 }
4759
4760 int player_set_max_adaptive_variant_limit(player_h player, int bandwidth, int width, int height)
4761 {
4762         int ret = PLAYER_ERROR_NONE;
4763         player_cli_s *pc = (player_cli_s *)player;
4764         muse_player_api_e api = MUSE_PLAYER_API_SET_MAX_ADAPTIVE_VARIANT_LIMIT;
4765         char *ret_buf = NULL;
4766
4767         PLAYER_INSTANCE_CHECK(player);
4768         PLAYER_CHECK_CONDITION(bandwidth >= -1 && width >= -1 && height >= -1,
4769                         PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
4770
4771         LOGD("ENTER");
4772
4773         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4774                                         MUSE_TYPE_INT, "bandwidth", bandwidth,
4775                                         MUSE_TYPE_INT, "width", width,
4776                                         MUSE_TYPE_INT, "height", height);
4777         g_free(ret_buf);
4778
4779         LOGD("LEAVE 0x%X", ret);
4780         return ret;
4781
4782 }
4783
4784 int player_get_max_adaptive_variant_limit(player_h player, int *pbandwidth, int *pwidth, int *pheight)
4785 {
4786         int ret = PLAYER_ERROR_NONE;
4787         player_cli_s *pc = (player_cli_s *)player;
4788         muse_player_api_e api = MUSE_PLAYER_API_GET_MAX_ADAPTIVE_VARIANT_LIMIT;
4789         char *ret_buf = NULL;
4790         int bandwidth = -1, width = -1, height = -1;
4791
4792         PLAYER_INSTANCE_CHECK(player);
4793         PLAYER_NULL_ARG_CHECK(pbandwidth || pwidth || pheight);
4794
4795         LOGD("ENTER");
4796
4797         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
4798         if (ret == PLAYER_ERROR_NONE) {
4799                 bool ret_val = true;
4800                 ret_val = _player_get_param_value(ret_buf,
4801                                                                                 MUSE_TYPE_INT, "bandwidth", (void *)&bandwidth,
4802                                                                                 MUSE_TYPE_INT, "width", (void *)&width,
4803                                                                                 MUSE_TYPE_INT, "height", (void *)&height,
4804                                                                                 INVALID_MUSE_TYPE_VALUE);
4805                 if (ret_val) {
4806                         if (pbandwidth) *pbandwidth = bandwidth;
4807                         if (pwidth) *pwidth = width;
4808                         if (pheight) *pheight = height;
4809                 } else {
4810                         ret = PLAYER_ERROR_INVALID_OPERATION;
4811                 }
4812         }
4813         g_free(ret_buf);
4814
4815         LOGD("LEAVE 0x%X", ret);
4816         return ret;
4817 }
4818
4819 int player_set_audio_only(player_h player, bool audio_only)
4820 {
4821         int ret = PLAYER_ERROR_NONE;
4822         player_cli_s *pc = (player_cli_s *)player;
4823         muse_player_api_e api = MUSE_PLAYER_API_SET_AUDIO_ONLY;
4824         char *ret_buf = NULL;
4825         player_state_e state = PLAYER_STATE_NONE;
4826
4827         PLAYER_INSTANCE_CHECK(player);
4828
4829         LOGD("ENTER audio_only: %d", audio_only);
4830
4831         /* check player state */
4832         if (_get_current_state(pc, &state) != PLAYER_ERROR_NONE) {
4833                 LOGE("Failed to get state");
4834                 return PLAYER_ERROR_INVALID_OPERATION;
4835         }
4836
4837         if (state < PLAYER_STATE_READY) {
4838                 LOGE("Invalid state %d", state);
4839                 return PLAYER_ERROR_INVALID_STATE;
4840         }
4841
4842         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "audio_only", (int)audio_only);
4843
4844         g_free(ret_buf);
4845
4846         LOGD("LEAVE 0x%X", ret);
4847
4848         return ret;
4849 }
4850
4851 int player_is_audio_only(player_h player, bool *paudio_only)
4852 {
4853         int ret = PLAYER_ERROR_NONE;
4854         muse_player_api_e api = MUSE_PLAYER_API_IS_AUDIO_ONLY;
4855         player_cli_s *pc = (player_cli_s *)player;
4856         char *ret_buf = NULL;
4857         int audio_only = 0;
4858
4859         PLAYER_INSTANCE_CHECK(player);
4860         PLAYER_NULL_ARG_CHECK(paudio_only);
4861
4862         LOGD("ENTER");
4863
4864         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
4865
4866         if (ret == PLAYER_ERROR_NONE) {
4867                 player_msg_get(audio_only, ret_buf);
4868                 *paudio_only = (bool)audio_only;
4869         }
4870
4871         g_free(ret_buf);
4872
4873         LOGD("LEAVE 0x%X", ret);
4874
4875         return ret;
4876 }
4877
4878 int player_set_streaming_buffering_time(player_h player, int prebuffer_ms, int rebuffer_ms)
4879 {
4880 #define MIN_BUFFER_TIME -1
4881         int ret = PLAYER_ERROR_NONE;
4882         player_cli_s *pc = (player_cli_s *)player;
4883         muse_player_api_e api = MUSE_PLAYER_API_SET_STREAMING_BUFFERING_TIME;
4884         char *ret_buf = NULL;
4885
4886         PLAYER_INSTANCE_CHECK(player);
4887         PLAYER_CHECK_CONDITION(prebuffer_ms >= MIN_BUFFER_TIME && rebuffer_ms >= MIN_BUFFER_TIME,
4888                         PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER");
4889
4890         LOGD("ENTER");
4891
4892         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
4893                                         MUSE_TYPE_INT, "prebuffer_ms", prebuffer_ms,
4894                                         MUSE_TYPE_INT, "rebuffer_ms", rebuffer_ms);
4895         g_free(ret_buf);
4896
4897         LOGD("LEAVE 0x%X", ret);
4898         return ret;
4899 }
4900
4901 int player_get_streaming_buffering_time(player_h player, int *prebuffer_ms, int *rebuffer_ms)
4902 {
4903         int ret = PLAYER_ERROR_NONE;
4904         muse_player_api_e api = MUSE_PLAYER_API_GET_STREAMING_BUFFERING_TIME;
4905         player_cli_s *pc = (player_cli_s *)player;
4906         int prebuffering_time = 0, rebuffering_time = 0;
4907         char *ret_buf = NULL;
4908
4909         PLAYER_INSTANCE_CHECK(player);
4910         PLAYER_NULL_ARG_CHECK(prebuffer_ms || rebuffer_ms);
4911
4912         LOGD("ENTER");
4913
4914         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
4915
4916         if (ret == PLAYER_ERROR_NONE) {
4917                 bool ret_val = true;
4918                 ret_val = _player_get_param_value(ret_buf,
4919                                                                                 MUSE_TYPE_INT, "prebuffer_ms", (void *)&prebuffering_time,
4920                                                                                 MUSE_TYPE_INT, "rebuffer_ms", (void *)&rebuffering_time,
4921                                                                                 INVALID_MUSE_TYPE_VALUE);
4922                 if (ret_val) {
4923                         if (prebuffer_ms) *prebuffer_ms = prebuffering_time;
4924                         if (rebuffer_ms) *rebuffer_ms = rebuffering_time;
4925                 } else {
4926                         ret = PLAYER_ERROR_INVALID_OPERATION;
4927                 }
4928         }
4929
4930         g_free(ret_buf);
4931
4932         LOGD("LEAVE 0x%X", ret);
4933         return ret;
4934 }
4935
4936 int player_360_is_content_spherical(player_h player, bool *is_spherical)
4937 {
4938         int ret = PLAYER_ERROR_NONE;
4939         muse_player_api_e api = MUSE_PLAYER_API_360_IS_CONTENT_SPHERICAL;
4940         player_cli_s *pc = (player_cli_s *)player;
4941         char *ret_buf = NULL;
4942         int val = 0;
4943
4944         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
4945         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
4946         PLAYER_INSTANCE_CHECK(player);
4947         PLAYER_NULL_ARG_CHECK(is_spherical);
4948
4949         LOGD("ENTER");
4950
4951         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
4952         if (ret == PLAYER_ERROR_NONE) {
4953                 player_msg_get(val, ret_buf);
4954                 *is_spherical = val;
4955         }
4956         g_free(ret_buf);
4957
4958         LOGD("LEAVE 0x%X", ret);
4959         return ret;
4960 }
4961
4962 int player_360_set_enabled(player_h player, bool enabled)
4963 {
4964         int ret = PLAYER_ERROR_NONE;
4965         muse_player_api_e api = MUSE_PLAYER_API_360_SET_ENABLED;
4966         player_cli_s *pc = (player_cli_s *)player;
4967         char *ret_buf = NULL;
4968         int val = (int)enabled;
4969
4970         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
4971         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
4972         PLAYER_INSTANCE_CHECK(player);
4973
4974         LOGD("ENTER %d", enabled);
4975
4976         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "val", val);
4977         g_free(ret_buf);
4978
4979         LOGD("LEAVE 0x%X", ret);
4980         return ret;
4981 }
4982
4983 int player_360_is_enabled(player_h player, bool *enabled)
4984 {
4985         int ret = PLAYER_ERROR_NONE;
4986         muse_player_api_e api = MUSE_PLAYER_API_360_IS_ENABLED;
4987         player_cli_s *pc = (player_cli_s *)player;
4988         char *ret_buf = NULL;
4989         int val = 0;
4990
4991         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
4992         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
4993         PLAYER_INSTANCE_CHECK(player);
4994         PLAYER_NULL_ARG_CHECK(enabled);
4995
4996         LOGD("ENTER");
4997
4998         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
4999         if (ret == PLAYER_ERROR_NONE) {
5000                 player_msg_get(val, ret_buf);
5001                 *enabled = val;
5002         }
5003         g_free(ret_buf);
5004
5005         LOGD("LEAVE 0x%X", ret);
5006         return ret;
5007 }
5008
5009 int player_360_set_direction_of_view(player_h player, float yaw, float pitch)
5010 {
5011         int ret = PLAYER_ERROR_NONE;
5012         muse_player_api_e api = MUSE_PLAYER_API_360_SET_DIRECTION_OF_VIEW;
5013         player_cli_s *pc = (player_cli_s *)player;
5014         char *ret_buf = NULL;
5015
5016         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
5017         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
5018         PLAYER_INSTANCE_CHECK(player);
5019         PLAYER_RANGE_ARG_CHECK(yaw, (float)-M_PI, (float)M_PI);
5020         PLAYER_RANGE_ARG_CHECK(pitch, ((float)-M_PI / 2), ((float)M_PI / 2));
5021
5022         LOGD("ENTER %f %f", yaw, pitch);
5023
5024         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
5025                                         MUSE_TYPE_DOUBLE, "yaw", (double)yaw,
5026                                         MUSE_TYPE_DOUBLE, "pitch", (double)pitch);
5027
5028         g_free(ret_buf);
5029
5030         LOGD("LEAVE 0x%X", ret);
5031         return ret;
5032 }
5033
5034 int player_360_get_direction_of_view(player_h player, float *yaw, float *pitch)
5035 {
5036         int ret = PLAYER_ERROR_NONE;
5037         muse_player_api_e api = MUSE_PLAYER_API_360_GET_DIRECTION_OF_VIEW;
5038         player_cli_s *pc = (player_cli_s *)player;
5039         double yaw_val = -1;
5040         double pitch_val = -1;
5041         char *ret_buf = NULL;
5042
5043         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
5044         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
5045         PLAYER_INSTANCE_CHECK(player);
5046         PLAYER_NULL_ARG_CHECK(yaw && pitch);
5047
5048         LOGD("ENTER");
5049
5050         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5051
5052         if (ret == PLAYER_ERROR_NONE) {
5053                 bool ret_val = true;
5054                 ret_val = _player_get_param_value(ret_buf,
5055                                                                                 MUSE_TYPE_DOUBLE, "yaw_val", (void *)&yaw_val,
5056                                                                                 MUSE_TYPE_DOUBLE, "pitch_val", (void *)&pitch_val,
5057                                                                                 INVALID_MUSE_TYPE_VALUE);
5058                 if (ret_val) {
5059                         *yaw = (float)yaw_val;
5060                         *pitch = (float)pitch_val;
5061                 } else {
5062                         LOGE("failed to get value from msg");
5063                         ret = PLAYER_ERROR_INVALID_OPERATION;
5064                 }
5065         }
5066
5067         g_free(ret_buf);
5068
5069         LOGD("LEAVE 0x%X", ret);
5070         return ret;
5071 }
5072
5073 int player_360_set_zoom(player_h player, float level)
5074 {
5075         int ret = PLAYER_ERROR_NONE;
5076         muse_player_api_e api = MUSE_PLAYER_API_360_SET_ZOOM;
5077         player_cli_s *pc = (player_cli_s *)player;
5078         char *ret_buf = NULL;
5079
5080         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
5081         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
5082         PLAYER_INSTANCE_CHECK(player);
5083         PLAYER_RANGE_ARG_CHECK(level, 1.0, 10.0);
5084
5085         LOGD("ENTER %f", level);
5086
5087         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_DOUBLE, "level", (double)level);
5088         g_free(ret_buf);
5089
5090         LOGD("LEAVE 0x%X", ret);
5091         return ret;
5092 }
5093
5094 int player_360_get_zoom(player_h player, float *level)
5095 {
5096         int ret = PLAYER_ERROR_NONE;
5097         muse_player_api_e api = MUSE_PLAYER_API_360_GET_ZOOM;
5098         player_cli_s *pc = (player_cli_s *)player;
5099         double zoom = -1;
5100         char *ret_buf = NULL;
5101
5102         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
5103         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
5104         PLAYER_INSTANCE_CHECK(player);
5105         PLAYER_NULL_ARG_CHECK(level);
5106
5107         LOGD("ENTER");
5108
5109         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5110
5111         if (ret == PLAYER_ERROR_NONE) {
5112                 if (player_msg_get_type(zoom, ret_buf, DOUBLE)) {
5113                         *level = (float)zoom;
5114                 } else {
5115                         LOGE("failed to get value from msg");
5116                         ret = PLAYER_ERROR_INVALID_OPERATION;
5117                 }
5118         }
5119
5120         g_free(ret_buf);
5121
5122         LOGD("LEAVE 0x%X", ret);
5123         return ret;
5124 }
5125
5126 int player_360_set_field_of_view(player_h player, int horizontal_degrees, int vertical_degrees)
5127 {
5128         int ret = PLAYER_ERROR_NONE;
5129         muse_player_api_e api = MUSE_PLAYER_API_360_SET_FIELD_OF_VIEW;
5130         player_cli_s *pc = (player_cli_s *)player;
5131         char *ret_buf = NULL;
5132
5133         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
5134         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
5135         PLAYER_INSTANCE_CHECK(player);
5136         PLAYER_RANGE_ARG_CHECK(horizontal_degrees, 1, 360);
5137         PLAYER_RANGE_ARG_CHECK(vertical_degrees, 1, 180);
5138
5139         LOGD("ENTER %d %d", horizontal_degrees, vertical_degrees);
5140
5141         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
5142                                         MUSE_TYPE_INT, "horizontal_degrees", horizontal_degrees,
5143                                         MUSE_TYPE_INT, "vertical_degrees", vertical_degrees);
5144         g_free(ret_buf);
5145
5146         LOGD("LEAVE 0x%X", ret);
5147         return ret;
5148 }
5149
5150 int player_360_get_field_of_view(player_h player, int *horizontal_degrees, int *vertical_degrees)
5151 {
5152         int ret = PLAYER_ERROR_NONE;
5153         muse_player_api_e api = MUSE_PLAYER_API_360_GET_FIELD_OF_VIEW;
5154         player_cli_s *pc = (player_cli_s *)player;
5155         int h_val = -1;
5156         int v_val = -1;
5157         char *ret_buf = NULL;
5158
5159         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
5160         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
5161         PLAYER_INSTANCE_CHECK(player);
5162         PLAYER_NULL_ARG_CHECK(horizontal_degrees && vertical_degrees);
5163
5164         LOGD("ENTER");
5165
5166         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5167
5168         if (ret == PLAYER_ERROR_NONE) {
5169                 bool ret_val = true;
5170                 ret_val = _player_get_param_value(ret_buf,
5171                                                                                 MUSE_TYPE_INT, "h_val", (void *)&h_val,
5172                                                                                 MUSE_TYPE_INT, "v_val", (void *)&v_val,
5173                                                                                 INVALID_MUSE_TYPE_VALUE);
5174                 if (ret_val) {
5175                         *horizontal_degrees = h_val;
5176                         *vertical_degrees = v_val;
5177                 } else {
5178                         LOGE("failed to get value from msg");
5179                         ret = PLAYER_ERROR_INVALID_OPERATION;
5180                 }
5181         }
5182
5183         g_free(ret_buf);
5184
5185         LOGD("LEAVE 0x%X", ret);
5186         return ret;
5187 }
5188
5189 int player_360_set_zoom_with_field_of_view(player_h player, float level, int horizontal_degrees, int vertical_degrees)
5190 {
5191         int ret = PLAYER_ERROR_NONE;
5192         muse_player_api_e api = MUSE_PLAYER_API_360_SET_ZOOM_WITH_FIELD_OF_VIEW;
5193         player_cli_s *pc = (player_cli_s *)player;
5194         char *ret_buf = NULL;
5195
5196         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_OPENGL);
5197         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_SPHERICAL_VIDEO);
5198         PLAYER_INSTANCE_CHECK(player);
5199         PLAYER_RANGE_ARG_CHECK(horizontal_degrees, 1, 360);
5200         PLAYER_RANGE_ARG_CHECK(vertical_degrees, 1, 180);
5201         PLAYER_RANGE_ARG_CHECK(level, 1.0, 10.0);
5202
5203         LOGD("ENTER %f %d %d", level, horizontal_degrees, vertical_degrees);
5204
5205         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
5206                                         MUSE_TYPE_DOUBLE, "level", (double)level,
5207                                         MUSE_TYPE_INT, "horizontal_degrees", horizontal_degrees,
5208                                         MUSE_TYPE_INT, "vertical_degrees", vertical_degrees);
5209
5210         g_free(ret_buf);
5211         LOGD("LEAVE 0x%X", ret);
5212         return ret;
5213 }
5214
5215 int player_set_replaygain_enabled(player_h player, bool enabled)
5216 {
5217         int ret = PLAYER_ERROR_NONE;
5218         muse_player_api_e api = MUSE_PLAYER_API_SET_REPLAYGAIN_ENABLED;
5219         player_cli_s *pc = (player_cli_s *)player;
5220         char *ret_buf = NULL;
5221         int val = (int)enabled;
5222
5223         PLAYER_INSTANCE_CHECK(player);
5224
5225         LOGD("ENTER");
5226
5227         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "val", val);
5228         g_free(ret_buf);
5229         return ret;
5230 }
5231
5232 int player_is_replaygain_enabled(player_h player, bool *enabled)
5233 {
5234         int ret = PLAYER_ERROR_NONE;
5235         muse_player_api_e api = MUSE_PLAYER_API_IS_REPLAYGAIN_ENABLED;
5236         player_cli_s *pc = (player_cli_s *)player;
5237         char *ret_buf = NULL;
5238         int val = -1;
5239
5240         PLAYER_INSTANCE_CHECK(player);
5241         PLAYER_NULL_ARG_CHECK(enabled);
5242
5243         LOGD("ENTER");
5244
5245         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5246         if (ret == PLAYER_ERROR_NONE) {
5247                 player_msg_get(val, ret_buf);
5248                 *enabled = (bool)val;
5249         }
5250
5251         g_free(ret_buf);
5252         return ret;
5253 }
5254
5255 int player_audio_pitch_set_enabled(player_h player, bool enabled)
5256 {
5257         int ret = PLAYER_ERROR_NONE;
5258         muse_player_api_e api = MUSE_PLAYER_API_PITCH_SET_ENABLED;
5259         player_cli_s *pc = (player_cli_s *)player;
5260         char *ret_buf = NULL;
5261         int val = (int)enabled;
5262
5263         PLAYER_INSTANCE_CHECK(player);
5264
5265         LOGD("ENTER");
5266
5267         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "val", val);
5268         g_free(ret_buf);
5269         return ret;
5270 }
5271
5272 int player_audio_pitch_is_enabled(player_h player, bool *enabled)
5273 {
5274         int ret = PLAYER_ERROR_NONE;
5275         muse_player_api_e api = MUSE_PLAYER_API_PITCH_IS_ENABLED;
5276         player_cli_s *pc = (player_cli_s *)player;
5277         char *ret_buf = NULL;
5278         int val = -1;
5279
5280         PLAYER_INSTANCE_CHECK(player);
5281         PLAYER_NULL_ARG_CHECK(enabled);
5282
5283         LOGD("ENTER");
5284
5285         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5286         if (ret == PLAYER_ERROR_NONE) {
5287                 player_msg_get(val, ret_buf);
5288                 *enabled = (bool)val;
5289         }
5290
5291         g_free(ret_buf);
5292         return ret;
5293 }
5294
5295 int player_audio_pitch_set_value(player_h player, float value)
5296 {
5297         int ret = PLAYER_ERROR_NONE;
5298         muse_player_api_e api = MUSE_PLAYER_API_PITCH_SET_VALUE;
5299         player_cli_s *pc = (player_cli_s *)player;
5300         char *ret_buf = NULL;
5301
5302         PLAYER_INSTANCE_CHECK(player);
5303         PLAYER_RANGE_ARG_CHECK(value, 0.5, 2.0);
5304
5305         LOGD("ENTER %1.3f", value);
5306
5307         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_DOUBLE, "pitch", (double)value);
5308         g_free(ret_buf);
5309
5310         LOGD("LEAVE 0x%X", ret);
5311         return ret;
5312 }
5313
5314 int player_audio_pitch_get_value(player_h player, float *value)
5315 {
5316         int ret = PLAYER_ERROR_NONE;
5317         muse_player_api_e api = MUSE_PLAYER_API_PITCH_GET_VALUE;
5318         player_cli_s *pc = (player_cli_s *)player;
5319         double pitch = 0.0;
5320         char *ret_buf = NULL;
5321
5322         PLAYER_INSTANCE_CHECK(player);
5323         PLAYER_NULL_ARG_CHECK(value);
5324
5325         LOGD("ENTER");
5326
5327         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5328
5329         if (ret == PLAYER_ERROR_NONE) {
5330                 if (player_msg_get_type(pitch, ret_buf, DOUBLE)) {
5331                         *value = (float)pitch;
5332                 } else {
5333                         LOGE("failed to get pitch value");
5334                         ret = PLAYER_ERROR_INVALID_OPERATION;
5335                 }
5336         }
5337
5338         g_free(ret_buf);
5339
5340         LOGD("LEAVE 0x%X", ret);
5341         return ret;
5342 }
5343
5344 int player_audio_offload_foreach_supported_format(player_h player, player_supported_media_format_cb callback, void *user_data)
5345 {
5346         int ret = PLAYER_ERROR_NONE;
5347         player_cli_s *pc = (player_cli_s *)player;
5348         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_OFFLOAD_GET_SUPPORTED_FORMAT;
5349         char *ret_buf = NULL;
5350         int format_info[MAX_SUPPORTED_MEDIA_FORMAT] = {0,};
5351         int len = 0, idx = 0;
5352
5353         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_AUDIO_OFFLOAD);
5354         PLAYER_INSTANCE_CHECK(player);
5355         PLAYER_NULL_ARG_CHECK(callback);
5356
5357         LOGD("ENTER");
5358
5359         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5360
5361         player_msg_get_type(len, ret_buf, INT);
5362         player_msg_get_array(format_info, ret_buf);
5363
5364         LOGD("num of format %d", len);
5365         for (idx = 0 ; idx < len ; idx++) {
5366                 if (!callback(format_info[idx], user_data)) {
5367                         LOGW("stop foreach callback");
5368                         break;
5369                 }
5370         }
5371
5372         LOGD("LEAVE 0x%X", ret);
5373         g_free(ret_buf);
5374         return ret;
5375 }
5376
5377 int player_audio_offload_set_enabled(player_h player, bool enabled)
5378 {
5379         int ret = PLAYER_ERROR_NONE;
5380         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_OFFLOAD_SET_ENABLED;
5381         player_cli_s *pc = (player_cli_s *)player;
5382         char *ret_buf = NULL;
5383         int val = (int)enabled;
5384
5385         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_AUDIO_OFFLOAD);
5386         PLAYER_INSTANCE_CHECK(player);
5387
5388         LOGD("ENTER");
5389
5390         PLAYER_SEND_MSG(api, pc, ret_buf, ret, MUSE_TYPE_INT, "val", val);
5391         g_free(ret_buf);
5392         return ret;
5393 }
5394
5395 int player_audio_offload_is_enabled(player_h player, bool *enabled)
5396 {
5397         int ret = PLAYER_ERROR_NONE;
5398         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_OFFLOAD_IS_ENABLED;
5399         player_cli_s *pc = (player_cli_s *)player;
5400         char *ret_buf = NULL;
5401         int val = -1;
5402
5403         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_AUDIO_OFFLOAD);
5404         PLAYER_INSTANCE_CHECK(player);
5405         PLAYER_NULL_ARG_CHECK(enabled);
5406
5407         LOGD("ENTER");
5408
5409         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5410         if (ret == PLAYER_ERROR_NONE) {
5411                 player_msg_get(val, ret_buf);
5412                 *enabled = (bool)val;
5413         }
5414
5415         g_free(ret_buf);
5416         return ret;
5417 }
5418
5419 int player_audio_offload_is_activated(player_h player, bool *activated)
5420 {
5421         int ret = PLAYER_ERROR_NONE;
5422         muse_player_api_e api = MUSE_PLAYER_API_AUDIO_OFFLOAD_IS_ACTIVATED;
5423         player_cli_s *pc = (player_cli_s *)player;
5424         char *ret_buf = NULL;
5425         int val = -1;
5426
5427         PLAYER_FEATURE_CHECK(PLAYER_FEATURE_AUDIO_OFFLOAD);
5428         PLAYER_INSTANCE_CHECK(player);
5429         PLAYER_NULL_ARG_CHECK(activated);
5430
5431         LOGD("ENTER");
5432
5433         PLAYER_SEND_MSG(api, pc, ret_buf, ret);
5434         if (ret == PLAYER_ERROR_NONE) {
5435                 player_msg_get(val, ret_buf);
5436                 *activated = (bool)val;
5437         }
5438
5439         g_free(ret_buf);
5440         return ret;
5441 }
5442
5443 int player_set_audio_codec_type(player_h player, player_codec_type_e codec_type)
5444 {
5445         PLAYER_INSTANCE_CHECK(player);
5446         PLAYER_RANGE_ARG_CHECK(codec_type, PLAYER_CODEC_TYPE_HW, PLAYER_CODEC_TYPE_SW);
5447
5448         int ret = PLAYER_ERROR_NONE;
5449         muse_player_api_e api = MUSE_PLAYER_API_SET_CODEC_TYPE;
5450         player_cli_s *pc = (player_cli_s *)player;
5451         char *ret_buf = NULL;
5452
5453         LOGD("ENTER codec: %d", codec_type);
5454
5455         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
5456                         MUSE_TYPE_INT, "stream_type", PLAYER_STREAM_TYPE_AUDIO,
5457                         MUSE_TYPE_INT, "codec_type", codec_type);
5458
5459         g_free(ret_buf);
5460         LOGD("LEAVE");
5461         return ret;
5462
5463 }
5464
5465 int player_get_audio_codec_type(player_h player, player_codec_type_e *codec_type)
5466 {
5467         PLAYER_INSTANCE_CHECK(player);
5468         PLAYER_NULL_ARG_CHECK(codec_type);
5469
5470         int ret = PLAYER_ERROR_NONE;
5471         muse_player_api_e api = MUSE_PLAYER_API_GET_CODEC_TYPE;
5472         player_cli_s *pc = (player_cli_s *)player;
5473         char *ret_buf = NULL;
5474         int type = 0;
5475
5476         LOGD("ENTER");
5477
5478         PLAYER_SEND_MSG(api, pc, ret_buf, ret,
5479                         MUSE_TYPE_INT, "stream_type", PLAYER_STREAM_TYPE_AUDIO);
5480         if (ret == PLAYER_ERROR_NONE) {
5481                 player_msg_get(type, ret_buf);
5482                 *codec_type = type;
5483         }
5484
5485         g_free(ret_buf);
5486         LOGD("LEAVE codec: %d", *codec_type);
5487         return ret;
5488 }