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