Merge "Fixed SVACE critical issues" into tizen_3.0
[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
34 #include "mm_player_utils.h"
35
36 int util_exist_file_path(const char *file_path)
37 {
38         int fd = 0;
39         struct stat stat_results = {0, };
40
41         if (!file_path || !strlen(file_path))
42                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
43
44         fd = open(file_path, O_RDONLY);
45
46         if (fd < 0) {
47                 char str_error[256];
48                 strerror_r(errno, str_error, sizeof(str_error));
49                 LOGE("failed to open file by %s (%d)", str_error, errno);
50
51                 if (EACCES == errno)
52                         return MM_ERROR_PLAYER_PERMISSION_DENIED;
53
54                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
55         }
56
57         if (fstat(fd, &stat_results) < 0) {
58                 LOGE("failed to get file status");
59         } else if (stat_results.st_size == 0) {
60                 LOGE("file size is zero");
61                 close(fd);
62                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
63         } else
64                 LOGW("file size : %lld bytes", (long long)stat_results.st_size);
65
66         close(fd);
67
68         return MM_ERROR_NONE;
69 }
70
71 bool util_write_file_backup(const char *backup_path, char *data_ptr, int data_size)
72 {
73         FILE *fp = NULL;
74         int wsize = 0;
75
76         fp = fopen(backup_path, "wb");
77         if (!fp)
78                 return FALSE;
79
80         wsize = fwrite(data_ptr, sizeof(char), data_size, fp);
81
82         fclose(fp);
83
84         if (wsize != data_size) {
85                 if (!access(backup_path, R_OK))
86                         remove(backup_path);
87
88                 LOGE("No space to write!\n");
89
90                 return FALSE;
91         }
92
93         return TRUE;
94 }
95
96 bool util_remove_file_backup(const char *backup_path)
97 {
98         if (!backup_path || !strlen(backup_path))
99                 return FALSE;
100
101         int res = access(backup_path, R_OK);
102         if (!res) {
103                 if (remove(backup_path) == -1)
104                         return FALSE;
105         }
106
107         return TRUE;
108 }
109
110 #define DETECTION_PREFIX_SIZE   20
111 int util_is_midi_type_by_mem(void *mem, int size)
112 {
113         const char *p = (const char *)mem;
114
115         if (size < DETECTION_PREFIX_SIZE)
116                 return MM_AUDIO_CODEC_INVALID;
117
118         /* mmf file detection */
119         if (p[0] == 'M' && p[1] == 'M' && p[2] == 'M' && p[3] == 'D') {
120                 LOGD("MM_AUDIO_CODEC_MMF\n");
121                 return MM_AUDIO_CODEC_MMF;
122         }
123
124         /* midi file detection */
125         if (p[0] == 'M' && p[1] == 'T' && p[2] == 'h' && p[3] == 'd') {
126                 LOGD("MM_AUDIO_CODEC_MIDI, %d\n", MM_AUDIO_CODEC_MIDI);
127                 return MM_AUDIO_CODEC_MIDI;
128         }
129         /* mxmf file detection */
130         if (p[0] == 'X' && p[1] == 'M' && p[2] == 'F' && p[3] == '_') {
131                 LOGD("MM_AUDIO_CODEC_MXMF\n");
132                 return MM_AUDIO_CODEC_MXMF;
133         }
134
135         /* wave file detection */
136         if (p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F' &&
137                 p[8] == 'W' && p[9] == 'A' && p[10] == 'V' && p[11] == 'E' &&
138                 p[12] == 'f' && p[13] == 'm' && p[14] == 't') {
139                 LOGD("MM_AUDIO_CODEC_WAVE\n");
140                 return MM_AUDIO_CODEC_WAVE;
141         }
142         /* i-melody file detection */
143         if (memcmp(p, "BEGIN:IMELODY", 13) == 0) {
144                 LOGD("MM_AUDIO_CODEC_IMELODY\n");
145                 return MM_AUDIO_CODEC_IMELODY;
146         }
147
148         return MM_AUDIO_CODEC_INVALID;
149 }
150
151 int util_is_midi_type_by_file(const char *file_path)
152 {
153         struct stat file_attrib;
154         FILE *fp = NULL;
155         char prefix[DETECTION_PREFIX_SIZE] = {0,};
156         int size;
157
158         if (!file_path)
159                 return FALSE;
160
161         fp = fopen(file_path, "r");
162
163         if (!fp)
164         return FALSE;
165
166         memset(&file_attrib, 0, sizeof(file_attrib));
167
168         if (stat(file_path, &file_attrib) != 0) {
169                 fclose(fp);
170                 return FALSE;
171         }
172
173         size = (int) file_attrib.st_size;
174
175         if (size < DETECTION_PREFIX_SIZE) {
176                 fclose(fp);
177                 return FALSE;
178         }
179
180         size = fread(prefix, sizeof(char), DETECTION_PREFIX_SIZE, fp);
181
182         fclose(fp);
183
184         return util_is_midi_type_by_mem(prefix, size);
185 }
186
187 char**
188 util_get_cookie_list(const char *cookies)
189 {
190         char **cookie_list = NULL;
191         char *temp = NULL;
192         gint i = 0;
193
194         if (!cookies || !strlen(cookies))
195                 return NULL;
196
197         SECURE_LOGD("cookies : %d[bytes] - %s \n", strlen(cookies), cookies);
198
199         temp = g_strdup(cookies);
200
201         /* trimming. it works inplace */
202         g_strstrip(temp);
203
204         /* split */
205         cookie_list = g_strsplit(temp, ";", 100);
206
207         for (i = 0; i < g_strv_length(cookie_list); i++) {
208                 if (cookie_list[i]) {
209                         if (strlen(cookie_list[i])) {
210                                 g_strstrip(cookie_list[i]);
211                                 SECURE_LOGD("cookie_list[%d] : %d[bytes] - %s \n", i, strlen(cookie_list[i]), cookie_list[i]);
212                         } else
213                                 cookie_list[i][0] = '\0';
214                 }
215         }
216
217         if (temp)
218                 g_free(temp);
219         temp = NULL;
220
221         return cookie_list;
222 }
223
224 bool util_check_valid_url(const char *proxy)
225 {
226         struct in_addr proxy_addr;
227         bool ret = TRUE;
228
229         MMPLAYER_RETURN_VAL_IF_FAIL(proxy, FALSE);
230         MMPLAYER_RETURN_VAL_IF_FAIL(strlen(proxy), FALSE);
231
232         if (inet_aton(proxy, &proxy_addr) != 0) {
233                 LOGW("invalid proxy is set. \n");
234                 ret = FALSE;
235         }
236
237         return ret;
238 }
239
240 /* check the given path is indicating sdp file */
241 bool
242 util_is_sdp_file(const char *path)
243 {
244         gboolean ret = FALSE;
245         gchar* uri = NULL;
246
247         MMPLAYER_FENTER();
248
249         MMPLAYER_RETURN_VAL_IF_FAIL(path, FALSE);
250
251         uri = g_ascii_strdown(path, -1);
252
253         if (uri == NULL)
254                 return FALSE;
255
256         /* trimming */
257         g_strstrip(uri);
258
259         /* strlen(".sdp") == 4 */
260         if (strlen(uri) <= 4) {
261                 LOGW("path is too short.\n");
262                 return ret;
263         }
264
265         /* first, check extension name */
266         ret = g_str_has_suffix(uri, "sdp");
267
268         /* second, if no suffix is there, check it's contents */
269         if (!ret)
270                 /* FIXIT : do it soon */
271                 LOGD("no suffix");
272
273         g_free(uri);
274         uri = NULL;
275
276         return ret;
277 }
278
279 int64_t
280 util_get_time(void)
281 {
282         struct timeval tv;
283         gettimeofday(&tv, NULL);
284         return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
285 }
286
287 int
288 util_get_rank_increase(const char *factory_class)
289 {
290         gint rank_pri_inc = 20;
291         gint rank_sec_inc = 10;
292         gint ret = 0;
293
294         if (g_strrstr(factory_class, "Dsp"))
295                 ret = rank_pri_inc;
296         else if (g_strrstr(factory_class, "HW"))
297                 ret = rank_pri_inc;
298         else if (g_strrstr(factory_class, "Arm"))
299                 ret = rank_sec_inc;
300
301         return ret;
302 }
303
304 int
305 util_factory_rank_compare(GstPluginFeature *f1, GstPluginFeature *f2)
306 {
307         const gchar *klass;
308         int f1_rank_inc = 0, f2_rank_inc = 0;
309
310         klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(f1));
311         f1_rank_inc = util_get_rank_increase(klass);
312
313         klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(f2));
314         f2_rank_inc = util_get_rank_increase(klass);
315
316         return (gst_plugin_feature_get_rank(f2)+f2_rank_inc) - (gst_plugin_feature_get_rank(f1)+f1_rank_inc);
317 }
318
319 const char*
320 util_get_charset(const char *file_path)
321 {
322         UCharsetDetector* ucsd;
323         const UCharsetMatch* ucm;
324         UErrorCode status = U_ZERO_ERROR;
325
326         const char* charset = NULL;
327         char *buf = NULL;
328         FILE* fin = 0;
329         size_t n_size = 0;
330
331         fin = fopen(file_path, "r");
332         if (!fin) {
333                 SECURE_LOGE("fail to open file %s\n", file_path);
334                 return NULL;
335         }
336
337         ucsd = ucsdet_open(&status);
338         if (U_FAILURE(status)) {
339                 LOGE("fail to ucsdet_open\n");
340                 goto done;
341         }
342
343         ucsdet_enableInputFilter(ucsd, TRUE);
344
345         buf = g_malloc(1024*1024);
346         if (!buf) {
347                 LOGE("fail to alloc\n");
348                 goto done;
349         }
350
351         n_size = fread(buf, 1, 1024*1024, fin);
352
353         if (!n_size)
354                 goto done;
355
356         ucsdet_setText(ucsd, buf, strlen(buf), &status);
357         if (U_FAILURE(status)) {
358                 LOGE("fail to ucsdet_setText\n");
359                 goto done;
360         }
361
362         ucm = ucsdet_detect(ucsd, &status);
363         if (U_FAILURE(status)) {
364                 LOGE("fail to ucsdet_detect\n");
365                 goto done;
366         }
367
368         charset = ucsdet_getName(ucm, &status);
369         if (U_FAILURE(status)) {
370                 LOGE("fail to ucsdet_getName\n");
371                 goto done;
372         }
373
374         /* CP949 encoding is an extension of the EUC-KR and it is backwards compatible.*/
375         if (charset && !strcmp(charset, "EUC-KR"))
376                 charset = "CP949";
377
378 done:
379         if (fin)
380                 fclose(fin);
381
382         if (ucsd)
383                 ucsdet_close(ucsd);
384
385         if (buf)
386                 g_free(buf);
387
388         return charset;
389 }
390
391 int util_get_pixtype(unsigned int fourcc)
392 {
393         int pixtype = MM_PIXEL_FORMAT_INVALID;
394
395     /*
396         char *pfourcc = (char*)&fourcc;
397
398         LOGD("fourcc(%c%c%c%c)",
399                 pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
400     */
401
402         switch (fourcc) {
403         case GST_MAKE_FOURCC('S', 'N', '1', '2'):
404         case GST_MAKE_FOURCC('N', 'V', '1', '2'):
405                 pixtype = MM_PIXEL_FORMAT_NV12;
406                 break;
407         case GST_MAKE_FOURCC('S', 'T', '1', '2'):
408                 pixtype = MM_PIXEL_FORMAT_NV12T;
409                 break;
410         case GST_MAKE_FOURCC('S', 'N', '2', '1'):
411         case GST_MAKE_FOURCC('N', 'V', '2', '1'):
412                 pixtype = MM_PIXEL_FORMAT_NV21;
413                 break;
414         case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
415         case GST_MAKE_FOURCC('Y', 'U', 'Y', 'V'):
416         case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'):
417                 pixtype = MM_PIXEL_FORMAT_YUYV;
418                 break;
419         case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
420         case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
421                 pixtype = MM_PIXEL_FORMAT_UYVY;
422                 break;
423         case GST_MAKE_FOURCC('S', '4', '2', '0'):
424         case GST_MAKE_FOURCC('I', '4', '2', '0'):
425                 pixtype = MM_PIXEL_FORMAT_I420;
426                 break;
427         case GST_MAKE_FOURCC('Y', 'V', '1', '2'):
428                 pixtype = MM_PIXEL_FORMAT_YV12;
429                 break;
430         case GST_MAKE_FOURCC('4', '2', '2', 'P'):
431                 pixtype = MM_PIXEL_FORMAT_422P;
432                 break;
433         case GST_MAKE_FOURCC('R', 'G', 'B', 'P'):
434                 pixtype = MM_PIXEL_FORMAT_RGB565;
435                 break;
436         case GST_MAKE_FOURCC('R', 'G', 'B', '3'):
437                 pixtype = MM_PIXEL_FORMAT_RGB888;
438                 break;
439         case GST_MAKE_FOURCC('A', 'R', 'G', 'B'):
440         case GST_MAKE_FOURCC('x', 'R', 'G', 'B'):
441                 pixtype = MM_PIXEL_FORMAT_ARGB;
442                 break;
443         case GST_MAKE_FOURCC('B', 'G', 'R', 'A'):
444         case GST_MAKE_FOURCC('B', 'G', 'R', 'x'):
445         case GST_MAKE_FOURCC('S', 'R', '3', '2'):
446                 pixtype = MM_PIXEL_FORMAT_RGBA;
447                 break;
448         case GST_MAKE_FOURCC('J', 'P', 'E', 'G'):
449         case GST_MAKE_FOURCC('P', 'N', 'G', ' '):
450                 pixtype = MM_PIXEL_FORMAT_ENCODED;
451                 break;
452         case GST_MAKE_FOURCC('I', 'T', 'L', 'V'):
453                 pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
454                 break;
455         default:
456                 LOGE("Not supported fourcc type(%c%c%c%c)",
457                         fourcc, fourcc>>8, fourcc>>16, fourcc>>24);
458                 pixtype = MM_PIXEL_FORMAT_INVALID;
459                 break;
460         }
461
462         return pixtype;
463 }