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