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