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