Updated to version 0.2.27
[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>, Heechul Jeon <heechul.jeon@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <unicode/ucsdet.h>
31
32 #include <mm_debug.h>
33 #include "mm_player_utils.h"
34
35 bool util_exist_file_path(const char *file_path)
36 {
37         int fd = -1;
38         struct stat stat_results = {0, };
39
40         if (!file_path || !strlen(file_path))
41                 return FALSE;
42
43         fd = open (file_path, O_RDONLY);
44
45         if (fd < 0)
46         {
47                 debug_error("failed to open %s, %s", file_path, strerror(errno));
48                 return FALSE;
49         }
50
51         if (fstat(fd, &stat_results) < 0)
52         {
53                 debug_error("failed to get file status");
54         }
55         else
56         {
57                 debug_warning("file size : %lld bytes", (long long)stat_results.st_size); //need to chech file validity
58         }
59
60         close(fd);
61
62         return TRUE;
63 }
64
65 bool util_write_file_backup(const char *backup_path, char *data_ptr, int data_size)
66 {
67         debug_log("\n");
68
69         FILE *fp = NULL;
70         int wsize = 0;
71
72         fp = fopen(backup_path, "wb");
73         if (!fp)
74                 return FALSE;
75
76         wsize = fwrite(data_ptr, sizeof(char), data_size, fp);
77
78         fclose(fp);
79
80         if (wsize != data_size) {
81                 if (!access(backup_path, R_OK))
82                         remove(backup_path);
83
84                 debug_error("No space to write!\n");
85
86                 return FALSE;
87         }
88
89         return TRUE;
90 }
91
92 bool util_remove_file_backup(const char *backup_path)
93 {
94         debug_log("\n");
95
96         if (!backup_path || !strlen(backup_path))
97                 return FALSE;
98
99         int res = access(backup_path, R_OK);
100         if (!res)
101         {
102                 if (remove(backup_path) == -1)
103                         return FALSE;
104         }
105
106         return TRUE;
107 }
108
109 #define DETECTION_PREFIX_SIZE   20
110 //bool util_is_midi_type_by_mem(void *mem, int size)
111 int util_is_midi_type_by_mem(void *mem, int size)
112 {
113         debug_log("\n");
114
115         const char *p = (const char *)mem;
116
117         if (size < DETECTION_PREFIX_SIZE)
118                 return MM_AUDIO_CODEC_INVALID;
119
120         /* mmf file detection */
121         if (p[0] == 'M' && p[1] == 'M' && p[2] == 'M' && p[3] == 'D') {
122                 debug_log("MM_AUDIO_CODEC_MMF\n");
123                 return MM_AUDIO_CODEC_MMF;
124         }
125
126         /* midi file detection */
127         if (p[0] == 'M' && p[1] == 'T' && p[2] == 'h' && p[3] == 'd') {
128                 debug_log ("MM_AUDIO_CODEC_MIDI, %d\n", MM_AUDIO_CODEC_MIDI);
129                 return MM_AUDIO_CODEC_MIDI;
130         }
131         /* mxmf file detection */
132         if (p[0] == 'X' && p[1] == 'M' && p[2] == 'F' && p[3] == '_') {
133                 debug_log ("MM_AUDIO_CODEC_MXMF\n");
134                 return MM_AUDIO_CODEC_MXMF;
135         }
136
137         /* wave file detection */
138         if (p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F' &&
139                 p[8] == 'W' && p[9] == 'A' && p[10] == 'V' && p[11] == 'E' &&
140                 p[12] == 'f' && p[13] == 'm' && p[14] == 't') {
141                 debug_log ("MM_AUDIO_CODEC_WAVE\n");
142                 return MM_AUDIO_CODEC_WAVE;
143         }
144         /* i-melody file detection */
145         if (memcmp(p, "BEGIN:IMELODY", 13) == 0)
146         {
147                 debug_log ("MM_AUDIO_CODEC_IMELODY\n");
148                 return MM_AUDIO_CODEC_IMELODY;
149         }
150
151         return MM_AUDIO_CODEC_INVALID;
152 }
153
154 //bool util_is_midi_type_by_file(const char *file_path)
155 int util_is_midi_type_by_file(const char *file_path)
156 {
157         debug_log("\n");
158
159         struct stat file_attrib;
160         FILE *fp = NULL;
161         char prefix[DETECTION_PREFIX_SIZE] = {0,};
162         int size;
163
164         if (!file_path)
165                 return FALSE;
166
167         fp = fopen(file_path, "r");
168
169         if (!fp)
170         return FALSE;
171
172         memset(&file_attrib, 0, sizeof(file_attrib));
173
174         if (stat(file_path, &file_attrib) != 0)
175         {
176                 fclose(fp);
177                 return FALSE;
178         }
179
180         size = (int) file_attrib.st_size;
181
182         if (size < DETECTION_PREFIX_SIZE)
183         {
184                 fclose(fp);
185                 return FALSE;
186         }
187
188         size = fread(prefix, sizeof(char), DETECTION_PREFIX_SIZE, fp);
189
190         fclose(fp);
191
192         return util_is_midi_type_by_mem(prefix, size);
193 }
194
195 /* messages are treated as warnings bcz those code should not be checked in.
196  * and no error handling will supported for same manner.
197  */
198 gboolean
199 __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
200 {
201         gint flag = (gint) u_data;
202         GstElement* parent = NULL;
203         GstMapInfo mapinfo = {0, };
204         gboolean ret = TRUE;
205
206         /* show name as default */
207         parent = (GstElement*)gst_object_get_parent(GST_OBJECT(pad));
208         debug_warning("PAD PROBE : %s:%s\n", GST_ELEMENT_NAME(parent), GST_PAD_NAME(pad));
209
210         /* show time stamp */
211         if ( flag & MM_PROBE_TIMESTAMP )
212         {
213                 debug_warning("ts : %u:%02u:%02u.%09u\n",  GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
214         }
215
216         /* show buffer size */
217         gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
218         if ( flag & MM_PROBE_BUFFERSIZE )
219         {
220                 debug_warning("buffer size : %ud\n", mapinfo.size);
221         }
222         gst_buffer_unmap(buffer, &mapinfo);
223
224         /* show buffer duration */
225         if ( flag & MM_PROBE_BUFFER_DURATION )
226         {
227                 debug_warning("dur : %lld\n", GST_BUFFER_DURATION(buffer));
228         }
229
230         /* show buffer caps */
231         if ( flag & MM_PROBE_CAPS )
232         {
233                 debug_warning("caps : %s\n", gst_caps_to_string(gst_pad_get_current_caps(pad)));
234         }
235
236         /* drop buffer if flag is on */
237         if ( flag & MM_PROBE_DROP_BUFFER )
238         {
239                 debug_warning("dropping\n");
240                 ret = FALSE;
241         }
242
243         /* show clock time */
244         if ( flag & MM_PROBE_CLOCK_TIME )
245         {
246                 GstClock* clock = NULL;
247                 GstClockTime now = GST_CLOCK_TIME_NONE;
248
249                 clock = GST_ELEMENT_CLOCK ( parent );
250
251                 if ( clock )
252                 {
253                         now = gst_clock_get_time( clock );
254                         debug_warning("clock time : %" GST_TIME_FORMAT "\n", GST_TIME_ARGS( now ));
255                 }
256         }
257
258         if ( parent )
259                 gst_object_unref(parent);
260
261         return ret;
262 }
263
264 char**
265 util_get_cookie_list ( const char *cookies )
266 {
267         char **cookie_list = NULL;
268         char *temp = NULL;
269         gint i = 0;
270
271         if ( !cookies || !strlen(cookies) )
272                 return NULL;
273
274         debug_log("cookies : %d[bytes] - %s \n", strlen(cookies), cookies);
275
276         temp = g_strdup(cookies);
277
278         /* trimming. it works inplace */
279         g_strstrip(temp);
280
281         /* split */
282         cookie_list = g_strsplit(temp, ";", 100);
283
284         for ( i = 0; i < g_strv_length(cookie_list); i++ )
285         {
286                 if ( cookie_list[i] && strlen(cookie_list[i]) )
287                 {
288                         g_strstrip(cookie_list[i]);
289                         debug_log("cookie_list[%d] : %d[bytes] - %s \n", i, strlen(cookie_list[i]), cookie_list[i]);
290                 }
291                 else
292                 {
293                         cookie_list[i][0]='\0';
294                 }
295         }
296
297         if (temp)
298                 g_free (temp);
299         temp=NULL;
300
301         return cookie_list;
302 }
303
304 bool util_check_valid_url ( const char *proxy )
305 {
306         struct in_addr proxy_addr;
307         bool ret = TRUE;
308
309         return_val_if_fail ( proxy, FALSE );
310         return_val_if_fail ( strlen(proxy), FALSE );
311
312        if ( inet_aton(proxy, &proxy_addr) != 0 )
313         {
314                 debug_warning("invalid proxy is set. \n");
315                 ret = FALSE;
316         }
317
318         return ret;
319 }
320
321 /* check the given path is indicating sdp file */
322 bool
323 util_is_sdp_file ( const char *path )
324 {
325         gboolean ret = FALSE;
326         gchar* uri = NULL;
327
328         debug_fenter();
329
330         return_val_if_fail ( path, FALSE );
331
332         uri = g_ascii_strdown ( path, -1 );
333
334         if ( uri == NULL)
335         {
336                 return FALSE;
337         }
338
339         /* trimming */
340         g_strstrip( uri );
341
342         /* strlen(".sdp") == 4 */
343         if ( strlen( uri ) <= 4 )
344         {
345                 debug_warning ( "path is too short.\n" );
346                 return ret;
347         }
348
349         /* first, check extension name */
350         ret = g_str_has_suffix ( uri, "sdp" );
351
352         /* second, if no suffix is there, check it's contents */
353         if ( ! ret )
354         {
355                 /* FIXIT : do it soon */
356                 debug_log("determining whether it's sdp or not with it's content is not implemented yet. ;)\n");
357         }
358
359         g_free( uri);
360         uri = NULL;
361
362         return ret;
363 }
364
365 int64_t
366 util_get_time ( void )
367 {
368         struct timeval tv;
369         gettimeofday(&tv,NULL);
370         return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
371 }
372
373 int
374 util_get_rank_increase ( const char *factory_class )
375 {
376         gint rank_pri_inc = 20;
377         gint rank_sec_inc = 10;
378         gint ret = 0;
379
380         if ( g_strrstr(factory_class,"Dsp") )
381                 ret = rank_pri_inc;
382         else if ( g_strrstr(factory_class,"HW") )
383                 ret = rank_pri_inc;
384         else if ( g_strrstr(factory_class,"Arm") )
385                 ret = rank_sec_inc;
386
387         return ret;
388 }
389
390 int
391 util_factory_rank_compare(GstPluginFeature *f1, GstPluginFeature *f2) // @
392 {
393         const gchar *klass;
394         int f1_rank_inc=0, f2_rank_inc=0;
395
396         klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(f1));
397         f1_rank_inc = util_get_rank_increase ( klass );
398
399         klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(f2));
400         f2_rank_inc = util_get_rank_increase ( klass );
401
402         return (gst_plugin_feature_get_rank(f2)+f2_rank_inc) - (gst_plugin_feature_get_rank(f1)+f1_rank_inc );
403 }
404
405 const char*
406 util_get_charset(const char *file_path)
407 {
408         UCharsetDetector* ucsd;
409         const UCharsetMatch* ucm;
410         UErrorCode status = U_ZERO_ERROR;
411
412         const char* charset = NULL;
413         char *buf = NULL;
414         FILE* fin;
415
416         fin = fopen(file_path, "r");
417         if (!fin)
418         {
419                 debug_error("fail to open file %s\n", file_path);
420                 return NULL;
421         }
422
423         ucsd = ucsdet_open( &status );
424         if( U_FAILURE(status) ) {
425                 debug_error("fail to ucsdet_open\n");
426                 return NULL;
427         }
428
429         ucsdet_enableInputFilter( ucsd, TRUE );
430
431         buf = g_malloc(1024*1024);
432         if (!buf)
433         {
434                 debug_error("fail to alloc\n");
435                 goto done;
436         }
437
438         fread( buf, 1, 1024*1024, fin );
439         fclose(fin);
440
441         ucsdet_setText( ucsd, buf, strlen(buf), &status );
442         if( U_FAILURE(status) ) {
443                 debug_error("fail to ucsdet_setText\n");
444                 goto done;
445         }
446
447         ucm = ucsdet_detect( ucsd, &status );
448         if( U_FAILURE(status) ) {
449                 debug_error("fail to ucsdet_detect\n");
450                 goto done;
451         }
452
453         charset = ucsdet_getName( ucm, &status );
454         if( U_FAILURE(status) ) {
455                 debug_error("fail to ucsdet_getName\n");
456                 goto done;
457         }
458
459 done:
460         ucsdet_close( ucsd );
461
462         if (buf)
463                 g_free(buf);
464
465         return charset;
466 }
467