[0.6.230] Use FIFO ticket lock when use command lock
[platform/core/multimedia/libmm-player.git] / src / mm_player_utils.c
1 /*
2  * libmm-player
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
7  * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <sys/time.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
31 #include <unicode/ucsdet.h>
32 #include <dlog.h>
33 #include <storage.h>
34 #include <tzplatform_config.h>
35 #include "mm_player_utils.h"
36 #include "media_format.h"
37
38 #define MEDIA_PATH_EXTERNAL tzplatform_getenv(TZ_SYS_STORAGE) /* external storage, sd card, usb */
39 #define FD_NUM_FOR_DEBUG 10
40 #define CMD_LOCK_TICKET_MAX (G_MAXUINT - 1)
41
42 const gchar *
43 _mmplayer_get_stream_type_name(int type)
44 {
45         switch (type) {
46         case MM_PLAYER_STREAM_TYPE_AUDIO:
47                 return "AUDIO";
48         case MM_PLAYER_STREAM_TYPE_VIDEO:
49                 return "VIDEO";
50         case MM_PLAYER_STREAM_TYPE_TEXT:
51                 return "TEXT";
52         case MM_PLAYER_STREAM_TYPE_DEFAULT: /* fall through */
53         case MM_PLAYER_STREAM_TYPE_MAX:     /* fall through */
54         default:
55                 return "INVAID";
56         }
57 }
58
59 const gchar *
60 _mmplayer_get_state_name(int state)
61 {
62         switch (state) {
63         case MM_PLAYER_STATE_NULL:
64                 return "NULL";
65         case MM_PLAYER_STATE_READY:
66                 return "READY";
67         case MM_PLAYER_STATE_PAUSED:
68                 return "PAUSED";
69         case MM_PLAYER_STATE_PLAYING:
70                 return "PLAYING";
71         case MM_PLAYER_STATE_NONE:
72                 return "NONE";
73         default:
74                 return "INVAID";
75         }
76 }
77
78 gboolean
79 _mmplayer_is_rtsp_streaming(mmplayer_t *player)
80 {
81         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
82
83         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP) ? TRUE : FALSE;
84 }
85
86 gboolean
87 _mmplayer_is_http_streaming(mmplayer_t *player)
88 {
89         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
90
91         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_HTTP) ? TRUE : FALSE;
92 }
93
94 gboolean
95 _mmplayer_is_streaming(mmplayer_t *player)
96 {
97         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
98
99         return (_mmplayer_is_rtsp_streaming(player) || _mmplayer_is_http_streaming(player)
100                 || _mmplayer_is_http_live_streaming(player) || _mmplayer_is_dash_streaming(player)
101                 || _mmplayer_is_smooth_streaming(player)) ? TRUE : FALSE;
102 }
103
104 gboolean
105 _mmplayer_is_live_streaming(mmplayer_t *player)
106 {
107         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
108
109         return (_mmplayer_is_rtsp_streaming(player) && player->streaming_type == STREAMING_SERVICE_LIVE) ? TRUE : FALSE;
110 }
111
112 gboolean
113 _mmplayer_is_http_live_streaming(mmplayer_t *player)
114 {
115         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
116
117         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS) ? TRUE : FALSE;
118 }
119
120 gboolean
121 _mmplayer_is_dash_streaming(mmplayer_t *player)
122 {
123         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
124
125         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_DASH) ? TRUE : FALSE;
126 }
127
128 gboolean
129 _mmplayer_is_smooth_streaming(mmplayer_t *player)
130 {
131         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
132
133         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_SS) ? TRUE : FALSE;
134 }
135
136 gboolean
137 _mmplayer_is_ms_buff_src(mmplayer_t *player)
138 {
139         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
140
141         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_MS_BUFF) ? TRUE : FALSE;
142 }
143
144 gboolean
145 _mmplayer_has_suffix(mmplayer_t *player, const gchar *suffix)
146 {
147         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
148         MMPLAYER_RETURN_VAL_IF_FAIL(suffix, FALSE);
149
150         gboolean ret = FALSE;
151         gchar *t_url = g_ascii_strdown(player->profile.uri, -1);
152         gchar *t_suffix = g_ascii_strdown(suffix, -1);
153         gchar *opt = strchr(t_url, '?');
154
155         if (opt)
156                 *opt = '\0';
157
158         ret = g_str_has_suffix(t_url, t_suffix);
159
160         MMPLAYER_FREEIF(t_url);
161         MMPLAYER_FREEIF(t_suffix);
162
163         return ret;
164 }
165
166 gboolean
167 _mmplayer_is_videosink_ready(mmplayer_t *player, int surface_type)
168 {
169         int curr_type = MM_DISPLAY_SURFACE_NUM;
170
171         if (!player ||
172                 !player->pipeline ||
173                 !player->pipeline->mainbin ||
174                 !player->pipeline->videobin ||
175                 !player->pipeline->videobin[MMPLAYER_V_BIN].gst ||
176                 !player->pipeline->videobin[MMPLAYER_V_SINK].gst) {
177                 LOGW("videosink is not ready yet");
178                 return FALSE;
179         }
180
181         if (surface_type == MM_DISPLAY_SURFACE_NUM) /* don't care the surface type */
182                 return TRUE;
183
184         mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &curr_type);
185
186         if (curr_type != surface_type) {
187                 LOGW("surface type is mismatched %d, %d", curr_type, surface_type);
188                 return FALSE;
189         }
190
191         return TRUE;
192 }
193
194 gboolean
195 _mmplayer_post_message(mmplayer_t *player, enum MMMessageType msgtype, MMMessageParamType *param)
196 {
197         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
198
199         if (!player->msg_cb)
200                 return FALSE;
201 #ifdef __DEBUG__
202         LOGD("Message (type : %d)  will be posted using msg-cb(%p).", msgtype, player->msg_cb);
203 #endif
204
205         player->msg_cb(msgtype, param, player->msg_cb_param);
206
207         return TRUE;
208 }
209
210 gboolean
211 _mmplayer_dump_pipeline_state(mmplayer_t *player)
212 {
213         GstIterator *iter = NULL;
214         gboolean done = FALSE;
215
216         GValue item = {0, };
217         GstElement *element = NULL;
218         GstElementFactory *factory = NULL;
219
220         GstState state = GST_STATE_VOID_PENDING;
221         GstState pending = GST_STATE_VOID_PENDING;
222         GstClockTime time = 200 * GST_MSECOND;
223
224         MMPLAYER_FENTER();
225
226         MMPLAYER_RETURN_VAL_IF_FAIL(player &&
227                 player->pipeline &&
228                 player->pipeline->mainbin,
229                 FALSE);
230
231         MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-error-dump");
232
233         iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
234
235         if (iter != NULL) {
236                 while (!done) {
237                         switch (gst_iterator_next(iter, &item)) {
238                         case GST_ITERATOR_OK:
239                                 element = g_value_get_object(&item);
240                                 if (element) {
241                                         gst_element_get_state(element, &state, &pending, time);
242
243                                         factory = gst_element_get_factory(element) ;
244                                         if (factory)
245                                                 LOGE("%s:%s : From:%s To:%s   refcount : %d", GST_OBJECT_NAME(factory) , GST_ELEMENT_NAME(element) ,
246                                                         gst_element_state_get_name(state), gst_element_state_get_name(pending) , GST_OBJECT_REFCOUNT_VALUE(element));
247                                 }
248                                 g_value_reset(&item);
249                                 break;
250                         case GST_ITERATOR_RESYNC:
251                                 gst_iterator_resync(iter);
252                                 break;
253                         case GST_ITERATOR_ERROR:
254                                 done = TRUE;
255                                 break;
256                         case GST_ITERATOR_DONE:
257                                 done = TRUE;
258                                 break;
259                         }
260                 }
261         }
262
263         element = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
264
265         gst_element_get_state(element, &state, &pending, time);
266
267         factory = gst_element_get_factory(element) ;
268
269         if (factory) {
270                 LOGE("%s:%s : From:%s To:%s  refcount : %d",
271                         GST_OBJECT_NAME(factory),
272                         GST_ELEMENT_NAME(element),
273                         gst_element_state_get_name(state),
274                         gst_element_state_get_name(pending),
275                         GST_OBJECT_REFCOUNT_VALUE(element));
276         }
277
278         g_value_unset(&item);
279
280         if (iter)
281                 gst_iterator_free(iter);
282
283         MMPLAYER_FLEAVE();
284
285         return FALSE;
286 }
287
288 int
289 _mmplayer_exist_file_path(const char *file_path)
290 {
291         int fd = 0;
292         struct stat stat_results = {0, };
293
294         if (!file_path || !strlen(file_path))
295                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
296
297         fd = open(file_path, O_RDONLY);
298
299         if (fd < 0) {
300                 char str_error[256];
301                 strerror_r(errno, str_error, sizeof(str_error));
302                 LOGE("failed to open file by %s (%d)", str_error, errno);
303
304                 if (EACCES == errno)
305                         return MM_ERROR_PLAYER_PERMISSION_DENIED;
306
307                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
308         }
309
310         if (fstat(fd, &stat_results) < 0) {
311                 LOGE("failed to get file status");
312         } else if (stat_results.st_size == 0) {
313                 LOGE("file size is zero");
314                 if (fd < FD_NUM_FOR_DEBUG)
315                         LOGW("close fd %d", fd);
316                 close(fd);
317                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
318         } else {
319                 LOGW("file size : %lld bytes", (long long)stat_results.st_size);
320         }
321
322         if (fd < FD_NUM_FOR_DEBUG)
323                 LOGW("close fd %d", fd);
324         close(fd);
325
326         return MM_ERROR_NONE;
327 }
328
329 char **
330 _mmplayer_get_cookie_list(const char *cookies)
331 {
332         char **cookie_list = NULL;
333         char *temp = NULL;
334         gint i = 0;
335
336         if (!cookies || !strlen(cookies))
337                 return NULL;
338
339         SECURE_LOGD("cookies : %zu[bytes] - %s", strlen(cookies), cookies);
340
341         temp = g_strdup(cookies);
342
343         /* trimming. it works inplace */
344         g_strstrip(temp);
345
346         /* split */
347         cookie_list = g_strsplit(temp, ";", 100);
348
349         if (!cookie_list) {
350                 LOGE("failed to get cookie list");
351                 goto EXIT;
352         }
353
354         for (i = 0; i < g_strv_length(cookie_list); i++) {
355                 if (cookie_list[i]) {
356                         if (strlen(cookie_list[i])) {
357                                 g_strstrip(cookie_list[i]);
358                                 SECURE_LOGD("cookie_list[%d] : %zu[bytes] - %s", i, strlen(cookie_list[i]), cookie_list[i]);
359                         } else {
360                                 cookie_list[i][0] = '\0';
361                         }
362                 }
363         }
364
365 EXIT:
366         MMPLAYER_FREEIF(temp);
367
368         return cookie_list;
369 }
370
371 /* check the given path is indicating sdp file */
372 bool
373 _mmplayer_is_sdp_file(const char *path)
374 {
375         gboolean ret = FALSE;
376         gchar *uri = NULL;
377
378         MMPLAYER_FENTER();
379
380         MMPLAYER_RETURN_VAL_IF_FAIL(path, FALSE);
381
382         uri = g_ascii_strdown(path, -1);
383
384         if (uri == NULL)
385                 return FALSE;
386
387         /* trimming */
388         g_strstrip(uri);
389
390         /* strlen(".sdp") == 4 */
391         if (strlen(uri) <= 4) {
392                 LOGW("path is too short.");
393                 MMPLAYER_FREEIF(uri);
394                 return ret;
395         }
396
397         /* first, check extension name */
398         ret = g_str_has_suffix(uri, "sdp");
399
400         /* second, if no suffix is there, check it's contents */
401         if (!ret)
402                 /* FIXIT : do it soon */
403                 LOGD("no suffix");
404
405         MMPLAYER_FREEIF(uri);
406
407         return ret;
408 }
409
410 const char *
411 _mmplayer_get_charset(const char *file_path)
412 {
413         UCharsetDetector *ucsd;
414         const UCharsetMatch *ucm;
415         UErrorCode status = U_ZERO_ERROR;
416
417         const char *charset = NULL;
418         char *buf = NULL;
419         FILE *fin = 0;
420         size_t n_size = 0;
421
422         fin = fopen(file_path, "r");
423         if (!fin) {
424                 SECURE_LOGE("fail to open file %s", file_path);
425                 return NULL;
426         }
427
428         ucsd = ucsdet_open(&status);
429         if (U_FAILURE(status)) {
430                 LOGE("fail to ucsdet_open");
431                 goto done;
432         }
433
434         ucsdet_enableInputFilter(ucsd, TRUE);
435
436         buf = g_try_malloc(1024 * 1024);
437         if (!buf) {
438                 LOGE("fail to alloc");
439                 goto done;
440         }
441
442         n_size = fread(buf, 1, 1024*1024, fin);
443         buf[1024 * 1024 - 1] = '\0';
444         if (!n_size)
445                 goto done;
446
447         ucsdet_setText(ucsd, buf, strlen(buf), &status);
448         if (U_FAILURE(status)) {
449                 LOGE("fail to ucsdet_setText");
450                 goto done;
451         }
452
453         ucm = ucsdet_detect(ucsd, &status);
454         if (U_FAILURE(status)) {
455                 LOGE("fail to ucsdet_detect");
456                 goto done;
457         }
458
459         charset = ucsdet_getName(ucm, &status);
460         if (U_FAILURE(status)) {
461                 LOGE("fail to ucsdet_getName");
462                 goto done;
463         }
464
465         /* CP949 encoding is an extension of the EUC-KR and it is backwards compatible.*/
466         if (charset && !strcmp(charset, "EUC-KR"))
467                 charset = "CP949";
468
469 done:
470         if (fin)
471                 fclose(fin);
472
473         if (ucsd)
474                 ucsdet_close(ucsd);
475
476         MMPLAYER_FREEIF(buf);
477
478         return charset;
479 }
480
481 int
482 _mmplayer_get_pixtype(unsigned int fourcc)
483 {
484         int pixtype = MM_PIXEL_FORMAT_INVALID;
485
486 #ifdef __DEBUG__
487         char *pfourcc = (char *)&fourcc;
488
489         LOGD("fourcc(%c%c%c%c)",
490                 pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
491 #endif
492
493         switch (fourcc) {
494         case GST_MAKE_FOURCC('S', 'N', '1', '2'):
495         case GST_MAKE_FOURCC('N', 'V', '1', '2'):
496                 pixtype = MM_PIXEL_FORMAT_NV12;
497                 break;
498         case GST_MAKE_FOURCC('S', 'T', '1', '2'):
499                 pixtype = MM_PIXEL_FORMAT_NV12T;
500                 break;
501         case GST_MAKE_FOURCC('S', 'N', '2', '1'):
502         case GST_MAKE_FOURCC('N', 'V', '2', '1'):
503                 pixtype = MM_PIXEL_FORMAT_NV21;
504                 break;
505         case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
506         case GST_MAKE_FOURCC('Y', 'U', 'Y', 'V'):
507         case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'):
508                 pixtype = MM_PIXEL_FORMAT_YUYV;
509                 break;
510         case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
511         case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
512                 pixtype = MM_PIXEL_FORMAT_UYVY;
513                 break;
514         case GST_MAKE_FOURCC('S', '4', '2', '0'):
515         case GST_MAKE_FOURCC('I', '4', '2', '0'):
516                 pixtype = MM_PIXEL_FORMAT_I420;
517                 break;
518         case GST_MAKE_FOURCC('Y', 'V', '1', '2'):
519                 pixtype = MM_PIXEL_FORMAT_YV12;
520                 break;
521         case GST_MAKE_FOURCC('4', '2', '2', 'P'):
522                 pixtype = MM_PIXEL_FORMAT_422P;
523                 break;
524         case GST_MAKE_FOURCC('R', 'G', 'B', 'P'):
525                 pixtype = MM_PIXEL_FORMAT_RGB565;
526                 break;
527         case GST_MAKE_FOURCC('R', 'G', 'B', '3'):
528                 pixtype = MM_PIXEL_FORMAT_RGB888;
529                 break;
530         case GST_MAKE_FOURCC('A', 'R', 'G', 'B'):
531         case GST_MAKE_FOURCC('x', 'R', 'G', 'B'):
532                 pixtype = MM_PIXEL_FORMAT_ARGB;
533                 break;
534         case GST_MAKE_FOURCC('B', 'G', 'R', 'A'):
535         case GST_MAKE_FOURCC('B', 'G', 'R', 'x'):
536         case GST_MAKE_FOURCC('S', 'R', '3', '2'):
537                 pixtype = MM_PIXEL_FORMAT_RGBA;
538                 break;
539         case GST_MAKE_FOURCC('J', 'P', 'E', 'G'):
540         case GST_MAKE_FOURCC('P', 'N', 'G', ' '):
541                 pixtype = MM_PIXEL_FORMAT_ENCODED;
542                 break;
543         case GST_MAKE_FOURCC('I', 'T', 'L', 'V'):
544                 pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
545                 break;
546         default:
547                 LOGE("Not supported fourcc type(%c%c%c%c)",
548                         fourcc, fourcc>>8, fourcc>>16, fourcc>>24);
549                 pixtype = MM_PIXEL_FORMAT_INVALID;
550                 break;
551         }
552
553         return pixtype;
554 }
555
556 static int
557 __mmplayer_storage_supported_cb(int storage_id, storage_type_e type,
558         storage_state_e state, const char *path, void *user_data)
559 {
560         mmplayer_storage_info_t *storage_info = (mmplayer_storage_info_t *)user_data;
561
562         MMPLAYER_RETURN_VAL_IF_FAIL(storage_info, FALSE);
563
564         if (type == storage_info->type && strstr(storage_info->path, path)) {
565                 storage_info->id = storage_id;
566                 storage_info->state = state;
567                 return FALSE;
568         }
569
570         return TRUE;
571 }
572
573 bool
574 _mmplayer_get_storage_info(const char *path, mmplayer_storage_info_t *storage_info)
575 {
576         int ret = 0;
577         const char *file_path = path;
578
579         MMPLAYER_RETURN_VAL_IF_FAIL(file_path && storage_info, false);
580
581         if (strncmp(file_path, "file://", strlen("file://")) == 0)
582                 file_path = path + 7; /* remove file prefix */
583
584         if (strncmp(file_path, MEDIA_PATH_EXTERNAL, strlen(MEDIA_PATH_EXTERNAL)) == 0) {
585                 storage_info->type = STORAGE_TYPE_EXTERNAL;
586
587                 memset(storage_info->path, 0x00, MM_MAX_URL_LEN);
588                 g_snprintf(storage_info->path, MM_MAX_URL_LEN, "%s", file_path);
589
590                 ret = storage_foreach_device_supported((storage_device_supported_cb)__mmplayer_storage_supported_cb, storage_info);
591                 if (ret != STORAGE_ERROR_NONE) {
592                         LOGE("failed to check supported storage 0x%x", ret);
593                         return false;
594                 }
595
596                 if (storage_info->state <= STORAGE_STATE_REMOVED) {
597                         LOGE("need to check the external storage state %d:%d", storage_info->id, storage_info->state);
598                         return false;
599                 }
600         } else {
601                 storage_info->type = STORAGE_TYPE_INTERNAL;
602                 storage_info->state = STORAGE_STATE_MOUNTED;
603         }
604
605         LOGD("storage info %d:%d:%d", storage_info->type, storage_info->id, storage_info->state);
606         return true;
607 }
608
609 media_format_mimetype_e _mmplayer_convert_audio_pcm_str_to_media_format_mime(const gchar *audio_pcm_str)
610 {
611         if (!audio_pcm_str) {
612                 LOGW("audio pcm str is NULL");
613                 return MEDIA_FORMAT_MAX;
614         }
615
616         if (strstr(audio_pcm_str, "S16LE"))
617                 return MEDIA_FORMAT_PCM_S16LE;
618         else if (strstr(audio_pcm_str, "S24LE"))
619                 return MEDIA_FORMAT_PCM_S24LE;
620         else if (strstr(audio_pcm_str, "S32LE"))
621                 return MEDIA_FORMAT_PCM_S32LE;
622         else if (strstr(audio_pcm_str, "S16BE"))
623                 return MEDIA_FORMAT_PCM_S16BE;
624         else if (strstr(audio_pcm_str, "S24BE"))
625                 return MEDIA_FORMAT_PCM_S24BE;
626         else if (strstr(audio_pcm_str, "S32BE"))
627                 return MEDIA_FORMAT_PCM_S32BE;
628         else if (strstr(audio_pcm_str, "F32LE"))
629                 return MEDIA_FORMAT_PCM_F32LE;
630         else if (strstr(audio_pcm_str, "F32BE"))
631                 return MEDIA_FORMAT_PCM_F32BE;
632         else if (strstr(audio_pcm_str, "U16LE"))
633                 return MEDIA_FORMAT_PCM_U16LE;
634         else if (strstr(audio_pcm_str, "U24LE"))
635                 return MEDIA_FORMAT_PCM_U24LE;
636         else if (strstr(audio_pcm_str, "U32LE"))
637                 return MEDIA_FORMAT_PCM_U32LE;
638         else if (strstr(audio_pcm_str, "U16BE"))
639                 return MEDIA_FORMAT_PCM_U16BE;
640         else if (strstr(audio_pcm_str, "U24BE"))
641                 return MEDIA_FORMAT_PCM_U24BE;
642         else if (strstr(audio_pcm_str, "U32BE"))
643                 return MEDIA_FORMAT_PCM_U32BE;
644         else {
645                 LOGW("Not supported audio pcm format str : %s", audio_pcm_str);
646                 return MEDIA_FORMAT_MAX;
647         }
648 }
649
650 gboolean _mmplayer_use_decodebin(mmplayer_t *player) /* MMPLAYER_USE_DECODEBIN(player) */
651 {
652         int audio_offload = 0;
653         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
654
655         mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_OFFLOAD, &audio_offload); /* user requirement */
656
657         if (MMPLAYER_IS_MS_BUFF_SRC(player) || player->ini.use_decodebin || audio_offload)
658                 return TRUE;
659
660         return FALSE;
661 }
662
663 void _mmplayer_cmd_lock_init(mmplayer_t *player)
664 {
665         MMPLAYER_FENTER();
666         MMPLAYER_RETURN_IF_FAIL(player);
667         player->cmd_lock = g_new0(mmplayer_ticket_lock_t, 1);
668         g_mutex_init(&player->cmd_lock->ticket_mutex);
669         g_cond_init(&player->cmd_lock->ticket_cond);
670         player->cmd_lock->ticket_queue_head = 0;
671         player->cmd_lock->ticket_queue_tail = 0;
672         MMPLAYER_FLEAVE();
673 }
674
675 void _mmplayer_cmd_lock_deinit(mmplayer_t *player)
676 {
677         MMPLAYER_FENTER();
678         MMPLAYER_RETURN_IF_FAIL(player && player->cmd_lock);
679         g_mutex_clear(&player->cmd_lock->ticket_mutex);
680         g_cond_clear(&player->cmd_lock->ticket_cond);
681         player->cmd_lock->ticket_queue_head = 0;
682         player->cmd_lock->ticket_queue_tail = 0;
683         g_free(player->cmd_lock);
684         MMPLAYER_FLEAVE();
685 }
686
687 void _mmplayer_cmd_lock(mmplayer_t *player)
688 {
689         guint64 queue_me;
690         GCond *cond;
691         GMutex *mutex;
692
693         MMPLAYER_FENTER();
694         MMPLAYER_RETURN_IF_FAIL(player && player->cmd_lock);
695
696         cond = &player->cmd_lock->ticket_cond;
697         mutex = &player->cmd_lock->ticket_mutex;
698         g_mutex_lock(mutex);
699         queue_me = player->cmd_lock->ticket_queue_tail;
700         player->cmd_lock->ticket_queue_tail = (queue_me + 1) % CMD_LOCK_TICKET_MAX;
701         while (queue_me != player->cmd_lock->ticket_queue_head)
702                 g_cond_wait(cond, mutex);
703         g_mutex_unlock(mutex);
704         MMPLAYER_FLEAVE();
705 }
706
707 gboolean _mmplayer_cmd_trylock(mmplayer_t *player)
708 {
709         GMutex *mutex;
710
711         MMPLAYER_FENTER();
712         MMPLAYER_RETURN_VAL_IF_FAIL(player && player->cmd_lock, FALSE);
713
714         mutex = &player->cmd_lock->ticket_mutex;
715
716         if (!g_mutex_trylock(mutex)) {
717                 MMPLAYER_FLEAVE();
718                 return FALSE;
719         }
720
721         if (player->cmd_lock->ticket_queue_tail != player->cmd_lock->ticket_queue_head) {
722                 g_mutex_unlock(mutex);
723                 MMPLAYER_FLEAVE();
724                 return FALSE;
725         }
726         g_mutex_unlock(mutex);
727
728         _mmplayer_cmd_lock(player);
729         MMPLAYER_FLEAVE();
730         return TRUE;
731 }
732
733 void _mmplayer_cmd_unlock(mmplayer_t *player)
734 {
735         GCond *cond;
736         GMutex *mutex;
737
738         MMPLAYER_FENTER();
739         MMPLAYER_RETURN_IF_FAIL(player && player->cmd_lock);
740
741         cond = &player->cmd_lock->ticket_cond;
742         mutex = &player->cmd_lock->ticket_mutex;
743
744         g_mutex_lock(mutex);
745         player->cmd_lock->ticket_queue_head =
746                 (player->cmd_lock->ticket_queue_head + 1) % CMD_LOCK_TICKET_MAX;
747         g_cond_broadcast(cond);
748         g_mutex_unlock(mutex);
749         MMPLAYER_FLEAVE();
750 }