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