Update to version tizen 2.3 API base on Gstreamer 1.x
[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/socket.h>
29 #include <sys/time.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <unicode/ucsdet.h>
33
34 #include <mm_debug.h>
35 #include "mm_player_utils.h"
36
37 /* for getting status of connecting external display */
38 #include <vconf.h>
39 #include <vconf-internal-sysman-keys.h>
40 #include <vconf-internal-wifi-keys.h>
41
42 int util_exist_file_path(const char *file_path)
43 {
44         int fd = 0;
45         struct stat stat_results = {0, };
46
47         if (!file_path || !strlen(file_path))
48                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
49
50         fd = open (file_path, O_RDONLY);
51
52         if (fd < 0)
53         {
54                 debug_error("failed to open file by %s (%d)", strerror(errno), errno);
55
56                 if (EACCES == errno)
57 //                      return MM_ERROR_PLAYER_PERMISSION_DENIED;
58
59                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
60         }
61
62         if (fstat(fd, &stat_results) < 0)
63         {
64                 debug_error("failed to get file status");
65         }
66         else if (stat_results.st_size == 0)
67         {
68                 debug_error("file size is zero");
69                 close(fd);
70                 return MM_ERROR_PLAYER_FILE_NOT_FOUND;
71         }
72         else
73         {
74                 debug_warning("file size : %lld bytes", (long long)stat_results.st_size);
75         }
76
77         close(fd);
78
79         return MM_ERROR_NONE;
80 }
81
82 bool util_write_file_backup(const char *backup_path, char *data_ptr, int data_size)
83 {
84         FILE *fp = NULL;
85         int wsize = 0;
86
87         fp = fopen(backup_path, "wb");
88         if (!fp)
89                 return FALSE;
90
91         wsize = fwrite(data_ptr, sizeof(char), data_size, fp);
92
93         fclose(fp);
94
95         if (wsize != data_size) {
96                 if (!access(backup_path, R_OK))
97                         remove(backup_path);
98
99                 debug_error("No space to write!\n");
100
101                 return FALSE;
102         }
103
104         return TRUE;
105 }
106
107 bool util_remove_file_backup(const char *backup_path)
108 {
109         if (!backup_path || !strlen(backup_path))
110                 return FALSE;
111
112         int res = access(backup_path, R_OK);
113         if (!res)
114         {
115                 if (remove(backup_path) == -1)
116                         return FALSE;
117         }
118
119         return TRUE;
120 }
121
122 #define DETECTION_PREFIX_SIZE   20
123 //bool util_is_midi_type_by_mem(void *mem, int size)
124 int util_is_midi_type_by_mem(void *mem, int size)
125 {
126         const char *p = (const char *)mem;
127
128         if (size < DETECTION_PREFIX_SIZE)
129                 return MM_AUDIO_CODEC_INVALID;
130
131         /* mmf file detection */
132         if (p[0] == 'M' && p[1] == 'M' && p[2] == 'M' && p[3] == 'D') {
133                 debug_log("MM_AUDIO_CODEC_MMF\n");
134                 return MM_AUDIO_CODEC_MMF;
135         }
136
137         /* midi file detection */
138         if (p[0] == 'M' && p[1] == 'T' && p[2] == 'h' && p[3] == 'd') {
139                 debug_log ("MM_AUDIO_CODEC_MIDI, %d\n", MM_AUDIO_CODEC_MIDI);
140                 return MM_AUDIO_CODEC_MIDI;
141         }
142         /* mxmf file detection */
143         if (p[0] == 'X' && p[1] == 'M' && p[2] == 'F' && p[3] == '_') {
144                 debug_log ("MM_AUDIO_CODEC_MXMF\n");
145                 return MM_AUDIO_CODEC_MXMF;
146         }
147
148         /* wave file detection */
149         if (p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F' &&
150                 p[8] == 'W' && p[9] == 'A' && p[10] == 'V' && p[11] == 'E' &&
151                 p[12] == 'f' && p[13] == 'm' && p[14] == 't') {
152                 debug_log ("MM_AUDIO_CODEC_WAVE\n");
153                 return MM_AUDIO_CODEC_WAVE;
154         }
155         /* i-melody file detection */
156         if (memcmp(p, "BEGIN:IMELODY", 13) == 0)
157         {
158                 debug_log ("MM_AUDIO_CODEC_IMELODY\n");
159                 return MM_AUDIO_CODEC_IMELODY;
160         }
161
162         return MM_AUDIO_CODEC_INVALID;
163 }
164
165 //bool util_is_midi_type_by_file(const char *file_path)
166 int util_is_midi_type_by_file(const char *file_path)
167 {
168         struct stat file_attrib;
169         FILE *fp = NULL;
170         char prefix[DETECTION_PREFIX_SIZE] = {0,};
171         int size;
172
173         if (!file_path)
174                 return FALSE;
175
176         fp = fopen(file_path, "r");
177
178         if (!fp)
179         return FALSE;
180
181         memset(&file_attrib, 0, sizeof(file_attrib));
182
183         if (stat(file_path, &file_attrib) != 0)
184         {
185                 fclose(fp);
186                 return FALSE;
187         }
188
189         size = (int) file_attrib.st_size;
190
191         if (size < DETECTION_PREFIX_SIZE)
192         {
193                 fclose(fp);
194                 return FALSE;
195         }
196
197         size = fread(prefix, sizeof(char), DETECTION_PREFIX_SIZE, fp);
198
199         fclose(fp);
200
201         return util_is_midi_type_by_mem(prefix, size);
202 }
203
204 /* messages are treated as warnings bcz those code should not be checked in.
205  * and no error handling will supported for same manner.
206  */
207 gboolean
208 __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
209 {
210         gint flag = (gint) u_data;
211         GstElement* parent = NULL;
212         GstMapInfo mapinfo = {0, };
213         gboolean ret = TRUE;
214
215         /* show name as default */
216         parent = (GstElement*)gst_object_get_parent(GST_OBJECT(pad));
217         debug_log("PAD PROBE : %s:%s\n", GST_ELEMENT_NAME(parent), GST_PAD_NAME(pad));
218
219         /* show time stamp */
220         if ( flag & MM_PROBE_TIMESTAMP )
221         {
222                 debug_log("ts : %u:%02u:%02u.%09u\n",  GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
223         }
224
225         /* show buffer size */
226         gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
227         if ( flag & MM_PROBE_BUFFERSIZE )
228         {
229                 debug_log("buffer size : %ud\n", mapinfo.size);
230         }
231         gst_buffer_unmap(buffer, &mapinfo);
232
233         /* show buffer duration */
234         if ( flag & MM_PROBE_BUFFER_DURATION )
235         {
236                 debug_log("dur : %lld\n", GST_BUFFER_DURATION(buffer));
237         }
238
239         /* show buffer caps */
240         if ( flag & MM_PROBE_CAPS )
241         {
242                 MMPLAYER_LOG_GST_CAPS_TYPE(gst_pad_get_current_caps(pad));
243         }
244
245         /* drop buffer if flag is on */
246         if ( flag & MM_PROBE_DROP_BUFFER )
247         {
248                 debug_log("dropping\n");
249                 ret = FALSE;
250         }
251
252         /* show clock time */
253         if ( flag & MM_PROBE_CLOCK_TIME )
254         {
255                 GstClock* clock = NULL;
256                 GstClockTime now = GST_CLOCK_TIME_NONE;
257
258                 clock = GST_ELEMENT_CLOCK ( parent );
259
260                 if ( clock )
261                 {
262                         now = gst_clock_get_time( clock );
263                         debug_log("clock time : %" GST_TIME_FORMAT "\n", GST_TIME_ARGS( now ));
264                 }
265         }
266
267         if ( parent )
268                 gst_object_unref(parent);
269
270         return ret;
271 }
272
273 char**
274 util_get_cookie_list ( const char *cookies )
275 {
276         char **cookie_list = NULL;
277         char *temp = NULL;
278         gint i = 0;
279
280         if ( !cookies || !strlen(cookies) )
281                 return NULL;
282
283         secure_debug_log("cookies : %d[bytes] - %s \n", strlen(cookies), cookies);
284
285         temp = g_strdup(cookies);
286
287         /* trimming. it works inplace */
288         g_strstrip(temp);
289
290         /* split */
291         cookie_list = g_strsplit(temp, ";", 100);
292
293         for ( i = 0; i < g_strv_length(cookie_list); i++ )
294         {
295                 if ( cookie_list[i] && strlen(cookie_list[i]) )
296                 {
297                         g_strstrip(cookie_list[i]);
298                         secure_debug_log("cookie_list[%d] : %d[bytes] - %s \n", i, strlen(cookie_list[i]), cookie_list[i]);
299                 }
300                 else
301                 {
302                         cookie_list[i][0]='\0';
303                 }
304         }
305
306         if (temp)
307                 g_free (temp);
308         temp=NULL;
309
310         return cookie_list;
311 }
312
313 bool util_check_valid_url ( const char *proxy )
314 {
315         struct in_addr proxy_addr;
316         bool ret = TRUE;
317
318         return_val_if_fail ( proxy, FALSE );
319         return_val_if_fail ( strlen(proxy), FALSE );
320
321         if ( inet_aton(proxy, &proxy_addr) != 0 )
322         {
323                 debug_warning("invalid proxy is set. \n");
324                 ret = FALSE;
325         }
326
327         return ret;
328 }
329
330 /* check the given path is indicating sdp file */
331 bool
332 util_is_sdp_file ( const char *path )
333 {
334         gboolean ret = FALSE;
335         gchar* uri = NULL;
336
337         MMPLAYER_FENTER();
338
339         return_val_if_fail ( path, FALSE );
340
341         uri = g_ascii_strdown ( path, -1 );
342
343         if ( uri == NULL)
344         {
345                 return FALSE;
346         }
347
348         /* trimming */
349         g_strstrip( uri );
350
351         /* strlen(".sdp") == 4 */
352         if ( strlen( uri ) <= 4 )
353         {
354                 debug_warning ( "path is too short.\n" );
355                 return ret;
356         }
357
358         /* first, check extension name */
359         ret = g_str_has_suffix ( uri, "sdp" );
360
361         /* second, if no suffix is there, check it's contents */
362         if ( ! ret )
363         {
364                 /* FIXIT : do it soon */
365         }
366
367         g_free( uri);
368         uri = NULL;
369
370         return ret;
371 }
372
373 int64_t
374 util_get_time ( void )
375 {
376         struct timeval tv;
377         gettimeofday(&tv,NULL);
378         return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
379 }
380
381 int
382 util_get_rank_increase ( const char *factory_class )
383 {
384         gint rank_pri_inc = 20;
385         gint rank_sec_inc = 10;
386         gint ret = 0;
387
388         if ( g_strrstr(factory_class,"Dsp") )
389                 ret = rank_pri_inc;
390         else if ( g_strrstr(factory_class,"HW") )
391                 ret = rank_pri_inc;
392         else if ( g_strrstr(factory_class,"Arm") )
393                 ret = rank_sec_inc;
394
395         return ret;
396 }
397
398 int
399 util_factory_rank_compare(GstPluginFeature *f1, GstPluginFeature *f2) // @
400 {
401         const gchar *klass;
402         int f1_rank_inc=0, f2_rank_inc=0;
403
404         klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(f1));
405         f1_rank_inc = util_get_rank_increase ( klass );
406
407         klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(f2));
408         f2_rank_inc = util_get_rank_increase ( klass );
409
410         return (gst_plugin_feature_get_rank(f2)+f2_rank_inc) - (gst_plugin_feature_get_rank(f1)+f1_rank_inc );
411 }
412
413 const char*
414 util_get_charset(const char *file_path)
415 {
416         UCharsetDetector* ucsd;
417         const UCharsetMatch* ucm;
418         UErrorCode status = U_ZERO_ERROR;
419
420         const char* charset = NULL;
421         char *buf = NULL;
422         FILE* fin =0;
423         size_t n_size = 0;
424
425         fin = fopen(file_path, "r");
426         if (!fin)
427         {
428                 secure_debug_error("fail to open file %s\n", file_path);
429                 return NULL;
430         }
431
432         ucsd = ucsdet_open( &status );
433         if( U_FAILURE(status) ) {
434                 debug_error("fail to ucsdet_open\n");
435                 goto done;
436         }
437
438         ucsdet_enableInputFilter( ucsd, TRUE );
439
440         buf = g_malloc(1024*1024);
441         if (!buf)
442         {
443                 debug_error("fail to alloc\n");
444                 goto done;
445         }
446
447         n_size = fread( buf, 1, 1024*1024, fin );
448
449         if (!n_size)
450                 goto done;
451
452         ucsdet_setText( ucsd, buf, strlen(buf), &status );
453         if( U_FAILURE(status) ) {
454                 debug_error("fail to ucsdet_setText\n");
455                 goto done;
456         }
457
458         ucm = ucsdet_detect( ucsd, &status );
459         if( U_FAILURE(status) ) {
460                 debug_error("fail to ucsdet_detect\n");
461                 goto done;
462         }
463
464         charset = ucsdet_getName( ucm, &status );
465         if( U_FAILURE(status) ) {
466                 debug_error("fail to ucsdet_getName\n");
467                 goto done;
468         }
469
470 done:
471         if(fin)
472                 fclose(fin);
473
474         if(ucsd)
475                 ucsdet_close( ucsd );
476
477         if (buf)
478                 g_free(buf);
479
480         return charset;
481 }
482
483 int
484 util_get_is_connected_external_display(void)
485 {
486   int is_connected_hdmi = -1;
487   int is_connected_mirroring = -1;
488
489 #if 0
490         if (vconf_get_int(VCONFKEY_SYSMAN_HDMI, &is_connected_hdmi))
491                 debug_error("[hdmi]vconf_set_int FAIL");
492         if (vconf_get_int(VCONFKEY_SCREEN_MIRRORING_STATE, &is_connected_mirroring))
493                 debug_error("[mirroring]vconf_set_int FAIL");
494
495         /* if conneted with external display */
496         if (is_connected_mirroring == VCONFKEY_SCREEN_MIRRORING_CONNECTED) {
497                 debug_warning ("connected with mirroring display");
498                 return MMPLAYER_DISPLAY_MIRRORING_ACTIVE;
499         }
500         if (is_connected_hdmi == VCONFKEY_SYSMAN_HDMI_CONNECTED) {
501                 debug_warning ("connected with external display");
502                 return MMPLAYER_DISPLAY_HDMI_ACTIVE;
503         }
504         if ((is_connected_mirroring == VCONFKEY_SCREEN_MIRRORING_ACTIVATED || is_connected_mirroring == VCONFKEY_SCREEN_MIRRORING_DEACTIVATED) && is_connected_hdmi == VCONFKEY_SYSMAN_HDMI_DISCONNECTED) {
505                 debug_warning ("non-connected status");
506                 return MMPLAYER_DISPLAY_NULL;
507         }
508 #endif
509         debug_error ("it is not registered (%d, %d)", is_connected_mirroring, is_connected_hdmi);
510         return -1;
511 }
512
513 gboolean util_is_miracast_connected(void)
514 {
515         int is_connected = 0;
516
517         if (vconf_get_bool(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &is_connected) ) {
518                 debug_error("failed to get miracast status key");
519                 return FALSE;
520         }
521
522         if (VCONFKEY_MIRACAST_WFD_SOURCE_ON == is_connected) {
523                 debug_warning("miracast connected");
524                 return TRUE;
525         }
526
527         return FALSE;
528 }
529
530 int util_get_pixtype(unsigned int fourcc)
531 {
532         int pixtype = MM_PIXEL_FORMAT_INVALID;
533
534     /*
535         char *pfourcc = (char*)&fourcc;
536
537         debug_log("fourcc(%c%c%c%c)",
538                          pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
539     */
540
541
542         switch (fourcc) {
543         case GST_MAKE_FOURCC ('S', 'N', '1', '2'):
544         case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
545                 pixtype = MM_PIXEL_FORMAT_NV12;
546                 break;
547         case GST_MAKE_FOURCC ('S', 'N', '2', '1'):
548         case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
549                 pixtype = MM_PIXEL_FORMAT_NV21;
550                 break;
551         case GST_MAKE_FOURCC ('S', 'U', 'Y', 'V'):
552         case GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V'):
553         case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
554                 pixtype = MM_PIXEL_FORMAT_YUYV;
555                 break;
556         case GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y'):
557         case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
558                 pixtype = MM_PIXEL_FORMAT_UYVY;
559                 break;
560         case GST_MAKE_FOURCC ('S', '4', '2', '0'):
561         case GST_MAKE_FOURCC ('I', '4', '2', '0'):
562                 pixtype = MM_PIXEL_FORMAT_I420;
563                 break;
564         case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
565                 pixtype = MM_PIXEL_FORMAT_YV12;
566                 break;
567         case GST_MAKE_FOURCC ('4', '2', '2', 'P'):
568                 pixtype = MM_PIXEL_FORMAT_422P;
569                 break;
570         case GST_MAKE_FOURCC ('R', 'G', 'B', 'P'):
571                 pixtype = MM_PIXEL_FORMAT_RGB565;
572                 break;
573         case GST_MAKE_FOURCC ('R', 'G', 'B', '3'):
574                 pixtype = MM_PIXEL_FORMAT_RGB888;
575                 break;
576         case GST_MAKE_FOURCC ('A', 'R', 'G', 'B'):
577         case GST_MAKE_FOURCC ('x', 'R', 'G', 'B'):
578                 pixtype = MM_PIXEL_FORMAT_ARGB;
579                 break;
580         case GST_MAKE_FOURCC ('B', 'G', 'R', 'A'):
581         case GST_MAKE_FOURCC ('B', 'G', 'R', 'x'):
582         case GST_MAKE_FOURCC ('S', 'R', '3', '2'):
583                 pixtype = MM_PIXEL_FORMAT_RGBA;
584                 break;
585         case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'):
586         case GST_MAKE_FOURCC ('P', 'N', 'G', ' '):
587                 pixtype = MM_PIXEL_FORMAT_ENCODED;
588                 break;
589         /*FIXME*/
590         case GST_MAKE_FOURCC ('I', 'T', 'L', 'V'):
591                 pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
592                 break;
593         default:
594                 debug_error("Not supported fourcc type(%c%c%c%c)",
595                                fourcc, fourcc>>8, fourcc>>16, fourcc>>24);
596                 pixtype = MM_PIXEL_FORMAT_INVALID;
597                 break;
598         }
599
600         return pixtype;
601 }