[0.6.134] fix svace issue
[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
37 #define MEDIA_PATH_EXTERNAL tzplatform_getenv(TZ_SYS_STORAGE) /* external storage, sd card, usb */
38
39 const gchar *
40 __get_stream_type_name(int type)
41 {
42         switch (type) {
43         case MM_PLAYER_STREAM_TYPE_AUDIO:
44                 return "AUDIO";
45         case MM_PLAYER_STREAM_TYPE_VIDEO:
46                 return "VIDEO";
47         case MM_PLAYER_STREAM_TYPE_TEXT:
48                 return "TEXT";
49         case MM_PLAYER_STREAM_TYPE_DEFAULT: /* fall through */
50         case MM_PLAYER_STREAM_TYPE_MAX:     /* fall through */
51         default:
52                 return "INVAID";
53         }
54 }
55
56 const gchar *
57 __get_state_name(int state)
58 {
59         switch (state) {
60         case MM_PLAYER_STATE_NULL:
61                 return "NULL";
62         case MM_PLAYER_STATE_READY:
63                 return "READY";
64         case MM_PLAYER_STATE_PAUSED:
65                 return "PAUSED";
66         case MM_PLAYER_STATE_PLAYING:
67                 return "PLAYING";
68         case MM_PLAYER_STATE_NONE:
69                 return "NONE";
70         default:
71                 return "INVAID";
72         }
73 }
74
75 gboolean
76 __is_rtsp_streaming(mm_player_t* player)
77 {
78         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
79
80         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP) ? TRUE : FALSE;
81 }
82
83 gboolean
84 __is_http_streaming(mm_player_t* player)
85 {
86         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
87
88         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_HTTP) ? TRUE : FALSE;
89 }
90
91 gboolean
92 __is_streaming(mm_player_t* player)
93 {
94         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
95
96         return (__is_http_progressive_down(player) || __is_rtsp_streaming(player) || __is_http_streaming(player)
97                 || __is_http_live_streaming(player) || __is_dash_streaming(player) || __is_smooth_streaming(player)) ? TRUE : FALSE;
98 }
99
100 gboolean
101 __is_live_streaming(mm_player_t* player)
102 {
103         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
104
105         return (__is_rtsp_streaming(player) && player->streaming_type == STREAMING_SERVICE_LIVE) ? TRUE : FALSE;
106 }
107
108 gboolean
109 __is_http_live_streaming(mm_player_t* player)
110 {
111         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
112
113         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS) ? TRUE : FALSE;
114 }
115
116 gboolean
117 __is_dash_streaming(mm_player_t* player)
118 {
119         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
120
121         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_DASH) ? TRUE : FALSE;
122 }
123
124 gboolean
125 __is_smooth_streaming(mm_player_t* player)
126 {
127         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
128
129         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_SS) ? TRUE : FALSE;
130 }
131
132
133 gboolean
134 __is_http_progressive_down(mm_player_t* player)
135 {
136         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
137
138         return ((player->pd_mode) ? TRUE : FALSE);
139 }
140
141 gboolean
142 __is_ms_buff_src(mm_player_t* player)
143 {
144         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
145
146         return (player->profile.uri_type == MM_PLAYER_URI_TYPE_MS_BUFF) ? TRUE : FALSE;
147 }
148
149 gboolean
150 __has_suffix(mm_player_t* player, const gchar* suffix)
151 {
152         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
153         MMPLAYER_RETURN_VAL_IF_FAIL(suffix, FALSE);
154
155         gboolean ret = FALSE;
156         gchar* t_url = g_ascii_strdown(player->profile.uri, -1);
157         gchar* t_suffix = g_ascii_strdown(suffix, -1);
158
159         if (g_str_has_suffix(player->profile.uri, suffix))
160                 ret = TRUE;
161
162         MMPLAYER_FREEIF(t_url);
163         MMPLAYER_FREEIF(t_suffix);
164
165         return ret;
166 }
167
168 gboolean
169 __mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param)
170 {
171         MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
172
173         if (!player->msg_cb)
174                 return FALSE;
175
176         //LOGD("Message (type : %d)  will be posted using msg-cb(%p). \n", msgtype, player->msg_cb);
177
178         player->msg_cb(msgtype, param, player->msg_cb_param);
179
180         return TRUE;
181 }
182
183 gboolean
184 __mmplayer_dump_pipeline_state(mm_player_t* player)
185 {
186         GstIterator*iter = NULL;
187         gboolean done = FALSE;
188
189         GValue item = {0, };
190         GstElement *element = NULL;
191         GstElementFactory *factory = NULL;
192
193         GstState state = GST_STATE_VOID_PENDING;
194         GstState pending = GST_STATE_VOID_PENDING;
195         GstClockTime time = 200*GST_MSECOND;
196
197         MMPLAYER_FENTER();
198
199         MMPLAYER_RETURN_VAL_IF_FAIL(player &&
200                 player->pipeline &&
201                 player->pipeline->mainbin,
202                 FALSE);
203
204         iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
205
206         if (iter != NULL) {
207                 while (!done) {
208                         switch (gst_iterator_next(iter, &item)) {
209                         case GST_ITERATOR_OK:
210                                 element = g_value_get_object(&item);
211                                 gst_element_get_state(element, &state, &pending, time);
212
213                                 factory = gst_element_get_factory(element) ;
214                                 if (factory)
215                                         LOGE("%s:%s : From:%s To:%s   refcount : %d\n", GST_OBJECT_NAME(factory) , GST_ELEMENT_NAME(element) ,
216                                                 gst_element_state_get_name(state), gst_element_state_get_name(pending) , GST_OBJECT_REFCOUNT_VALUE(element));
217                                 g_value_reset(&item);
218                                 break;
219                         case GST_ITERATOR_RESYNC:
220                                 gst_iterator_resync(iter);
221                                 break;
222                         case GST_ITERATOR_ERROR:
223                                 done = TRUE;
224                                 break;
225                         case GST_ITERATOR_DONE:
226                                 done = TRUE;
227                                 break;
228                         }
229                 }
230         }
231
232         element = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
233
234         gst_element_get_state(element, &state, &pending, time);
235
236         factory = gst_element_get_factory(element) ;
237
238         if (factory) {
239                 LOGE("%s:%s : From:%s To:%s  refcount : %d\n",
240                         GST_OBJECT_NAME(factory),
241                         GST_ELEMENT_NAME(element),
242                         gst_element_state_get_name(state),
243                         gst_element_state_get_name(pending),
244                         GST_OBJECT_REFCOUNT_VALUE(element));
245         }
246
247         g_value_unset(&item);
248
249         if (iter)
250                 gst_iterator_free(iter);
251
252         MMPLAYER_FLEAVE();
253
254         return FALSE;
255 }
256
257 int util_exist_file_path(const char *file_path)
258 {
259         int fd = 0;
260         struct stat stat_results = {0, };
261
262         if (!file_path || !strlen(file_path))
263                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
264
265         fd = open(file_path, O_RDONLY);
266
267         if (fd < 0) {
268                 char str_error[256];
269                 strerror_r(errno, str_error, sizeof(str_error));
270                 LOGE("failed to open file by %s (%d)", str_error, errno);
271
272                 if (EACCES == errno)
273                         return MM_ERROR_PLAYER_PERMISSION_DENIED;
274
275                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
276         }
277
278         if (fstat(fd, &stat_results) < 0) {
279                 LOGE("failed to get file status");
280         } else if (stat_results.st_size == 0) {
281                 LOGE("file size is zero");
282                 close(fd);
283                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
284         } else
285                 LOGW("file size : %lld bytes", (long long)stat_results.st_size);
286
287         close(fd);
288
289         return MM_ERROR_NONE;
290 }
291
292 char**
293 util_get_cookie_list(const char *cookies)
294 {
295         char **cookie_list = NULL;
296         char *temp = NULL;
297         gint i = 0;
298
299         if (!cookies || !strlen(cookies))
300                 return NULL;
301
302         SECURE_LOGD("cookies : %d[bytes] - %s \n", strlen(cookies), cookies);
303
304         temp = g_strdup(cookies);
305
306         /* trimming. it works inplace */
307         g_strstrip(temp);
308
309         /* split */
310         cookie_list = g_strsplit(temp, ";", 100);
311
312         if (!cookie_list) {
313                 LOGE("failed to get cookie list");
314                 goto EXIT;
315         }
316
317         for (i = 0; i < g_strv_length(cookie_list); i++) {
318                 if (cookie_list[i]) {
319                         if (strlen(cookie_list[i])) {
320                                 g_strstrip(cookie_list[i]);
321                                 SECURE_LOGD("cookie_list[%d] : %d[bytes] - %s \n", i, strlen(cookie_list[i]), cookie_list[i]);
322                         } else {
323                                 cookie_list[i][0] = '\0';
324                         }
325                 }
326         }
327
328 EXIT:
329         if (temp)
330                 g_free(temp);
331         temp = NULL;
332
333         return cookie_list;
334 }
335
336 /* check the given path is indicating sdp file */
337 bool
338 util_is_sdp_file(const char *path)
339 {
340         gboolean ret = FALSE;
341         gchar* uri = NULL;
342
343         MMPLAYER_FENTER();
344
345         MMPLAYER_RETURN_VAL_IF_FAIL(path, FALSE);
346
347         uri = g_ascii_strdown(path, -1);
348
349         if (uri == NULL)
350                 return FALSE;
351
352         /* trimming */
353         g_strstrip(uri);
354
355         /* strlen(".sdp") == 4 */
356         if (strlen(uri) <= 4) {
357                 LOGW("path is too short.\n");
358                 g_free(uri);
359                 return ret;
360         }
361
362         /* first, check extension name */
363         ret = g_str_has_suffix(uri, "sdp");
364
365         /* second, if no suffix is there, check it's contents */
366         if (!ret)
367                 /* FIXIT : do it soon */
368                 LOGD("no suffix");
369
370         g_free(uri);
371         uri = NULL;
372
373         return ret;
374 }
375
376 const char*
377 util_get_charset(const char *file_path)
378 {
379         UCharsetDetector* ucsd;
380         const UCharsetMatch* ucm;
381         UErrorCode status = U_ZERO_ERROR;
382
383         const char* charset = NULL;
384         char *buf = NULL;
385         FILE* fin = 0;
386         size_t n_size = 0;
387
388         fin = fopen(file_path, "r");
389         if (!fin) {
390                 SECURE_LOGE("fail to open file %s\n", file_path);
391                 return NULL;
392         }
393
394         ucsd = ucsdet_open(&status);
395         if (U_FAILURE(status)) {
396                 LOGE("fail to ucsdet_open\n");
397                 goto done;
398         }
399
400         ucsdet_enableInputFilter(ucsd, TRUE);
401
402         buf = g_malloc(1024*1024);
403         if (!buf) {
404                 LOGE("fail to alloc\n");
405                 goto done;
406         }
407
408         n_size = fread(buf, 1, 1024*1024, fin);
409         buf[1024 * 1024 - 1] = '\0';
410         if (!n_size)
411                 goto done;
412
413         ucsdet_setText(ucsd, buf, strlen(buf), &status);
414         if (U_FAILURE(status)) {
415                 LOGE("fail to ucsdet_setText\n");
416                 goto done;
417         }
418
419         ucm = ucsdet_detect(ucsd, &status);
420         if (U_FAILURE(status)) {
421                 LOGE("fail to ucsdet_detect\n");
422                 goto done;
423         }
424
425         charset = ucsdet_getName(ucm, &status);
426         if (U_FAILURE(status)) {
427                 LOGE("fail to ucsdet_getName\n");
428                 goto done;
429         }
430
431         /* CP949 encoding is an extension of the EUC-KR and it is backwards compatible.*/
432         if (charset && !strcmp(charset, "EUC-KR"))
433                 charset = "CP949";
434
435 done:
436         if (fin)
437                 fclose(fin);
438
439         if (ucsd)
440                 ucsdet_close(ucsd);
441
442         if (buf)
443                 g_free(buf);
444
445         return charset;
446 }
447
448 int util_get_pixtype(unsigned int fourcc)
449 {
450         int pixtype = MM_PIXEL_FORMAT_INVALID;
451
452     /*
453         char *pfourcc = (char*)&fourcc;
454
455         LOGD("fourcc(%c%c%c%c)",
456                 pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
457     */
458
459         switch (fourcc) {
460         case GST_MAKE_FOURCC('S', 'N', '1', '2'):
461         case GST_MAKE_FOURCC('N', 'V', '1', '2'):
462                 pixtype = MM_PIXEL_FORMAT_NV12;
463                 break;
464         case GST_MAKE_FOURCC('S', 'T', '1', '2'):
465                 pixtype = MM_PIXEL_FORMAT_NV12T;
466                 break;
467         case GST_MAKE_FOURCC('S', 'N', '2', '1'):
468         case GST_MAKE_FOURCC('N', 'V', '2', '1'):
469                 pixtype = MM_PIXEL_FORMAT_NV21;
470                 break;
471         case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
472         case GST_MAKE_FOURCC('Y', 'U', 'Y', 'V'):
473         case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'):
474                 pixtype = MM_PIXEL_FORMAT_YUYV;
475                 break;
476         case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
477         case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
478                 pixtype = MM_PIXEL_FORMAT_UYVY;
479                 break;
480         case GST_MAKE_FOURCC('S', '4', '2', '0'):
481         case GST_MAKE_FOURCC('I', '4', '2', '0'):
482                 pixtype = MM_PIXEL_FORMAT_I420;
483                 break;
484         case GST_MAKE_FOURCC('Y', 'V', '1', '2'):
485                 pixtype = MM_PIXEL_FORMAT_YV12;
486                 break;
487         case GST_MAKE_FOURCC('4', '2', '2', 'P'):
488                 pixtype = MM_PIXEL_FORMAT_422P;
489                 break;
490         case GST_MAKE_FOURCC('R', 'G', 'B', 'P'):
491                 pixtype = MM_PIXEL_FORMAT_RGB565;
492                 break;
493         case GST_MAKE_FOURCC('R', 'G', 'B', '3'):
494                 pixtype = MM_PIXEL_FORMAT_RGB888;
495                 break;
496         case GST_MAKE_FOURCC('A', 'R', 'G', 'B'):
497         case GST_MAKE_FOURCC('x', 'R', 'G', 'B'):
498                 pixtype = MM_PIXEL_FORMAT_ARGB;
499                 break;
500         case GST_MAKE_FOURCC('B', 'G', 'R', 'A'):
501         case GST_MAKE_FOURCC('B', 'G', 'R', 'x'):
502         case GST_MAKE_FOURCC('S', 'R', '3', '2'):
503                 pixtype = MM_PIXEL_FORMAT_RGBA;
504                 break;
505         case GST_MAKE_FOURCC('J', 'P', 'E', 'G'):
506         case GST_MAKE_FOURCC('P', 'N', 'G', ' '):
507                 pixtype = MM_PIXEL_FORMAT_ENCODED;
508                 break;
509         case GST_MAKE_FOURCC('I', 'T', 'L', 'V'):
510                 pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
511                 break;
512         default:
513                 LOGE("Not supported fourcc type(%c%c%c%c)",
514                         fourcc, fourcc>>8, fourcc>>16, fourcc>>24);
515                 pixtype = MM_PIXEL_FORMAT_INVALID;
516                 break;
517         }
518
519         return pixtype;
520 }
521
522 static int _util_storage_supported_cb(int storage_id, storage_type_e type,
523         storage_state_e state, const char *path, void *user_data)
524 {
525         MMPlayerStorageInfo *storage_info = (MMPlayerStorageInfo *)user_data;
526
527         MMPLAYER_RETURN_VAL_IF_FAIL(storage_info, FALSE);
528
529         if (type == storage_info->type && strstr(storage_info->path, path)) {
530                 storage_info->id = storage_id;
531                 storage_info->state = state;
532                 return FALSE;
533         }
534
535         return TRUE;
536 }
537
538 bool util_get_storage_info(const char *path, MMPlayerStorageInfo *storage_info)
539 {
540         int ret = 0;
541         const char *file_path = path;
542
543         MMPLAYER_RETURN_VAL_IF_FAIL(file_path && storage_info, false);
544
545         if (strncmp(file_path, "file://", strlen("file://")) == 0)
546                 file_path = path+7; /* remove file prefix */
547
548         if (strncmp(file_path, MEDIA_PATH_EXTERNAL, strlen(MEDIA_PATH_EXTERNAL)) == 0) {
549                 storage_info->type = STORAGE_TYPE_EXTERNAL;
550
551                 memset(storage_info->path, 0x00, MM_MAX_URL_LEN);
552                 g_snprintf(storage_info->path, MM_MAX_URL_LEN, "%s", file_path);
553
554                 ret = storage_foreach_device_supported((storage_device_supported_cb)_util_storage_supported_cb, storage_info);
555                 if (ret != STORAGE_ERROR_NONE) {
556                         LOGE("failed to check supported storage 0x%x", ret);
557                         return false;
558                 }
559
560                 if (storage_info->state <= STORAGE_STATE_REMOVED) {
561                         LOGE("need to check the external storage state %d:%d", storage_info->id, storage_info->state);
562                         return false;
563                 }
564         } else {
565                 storage_info->type = STORAGE_TYPE_INTERNAL;
566                 storage_info->state = STORAGE_STATE_MOUNTED;
567         }
568
569         LOGD("storage info %d:%d:%d", storage_info->type, storage_info->id, storage_info->state);
570         return true;
571 }