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