Fix Coverity issue
[platform/core/multimedia/libmm-streamrecorder.git] / src / mm_streamrecorder_util.c
1 /*
2  * libmm-streamrecorder
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyuntae Kim <ht1211.kim@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 /*=======================================================================================
23 |  INCLUDE FILES                                                                        |
24 =======================================================================================*/
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <sys/vfs.h>                    /* struct statfs */
28
29 #include "mm_streamrecorder_util.h"
30 #include <mm_types.h>
31 #include <mm_error.h>
32 #include <glib.h>
33 #include <stdlib.h>
34 #include "iniparser.h"
35 #include <glib/gstdio.h>
36 #include <gst/video/video-info.h>
37
38 /*-----------------------------------------------------------------------
39 |    GLOBAL VARIABLE DEFINITIONS for internal                           |
40 -----------------------------------------------------------------------*/
41
42 /*-----------------------------------------------------------------------
43 |    LOCAL VARIABLE DEFINITIONS for internal                            |
44 -----------------------------------------------------------------------*/
45 #define TIME_STRING_MAX_LEN     64
46
47 /*---------------------------------------------------------------------------
48 |    LOCAL FUNCTION PROTOTYPES:                                                                                         |
49 ---------------------------------------------------------------------------*/
50 /* STATIC INTERNAL FUNCTION */
51
52 /* static gint          skip_mdat(FILE *f); */
53
54 /*===========================================================================================
55 |                                                                                                                                                                                       |
56 |  FUNCTION DEFINITIONS                                                                                                                                         |
57 ========================================================================================== */
58 /*---------------------------------------------------------------------------
59 |    GLOBAL FUNCTION DEFINITIONS:                                                                                       |
60 ---------------------------------------------------------------------------*/
61
62 gint32 _mmstreamrecorder_double_to_fix(gdouble d_number)
63 {
64         return (gint32) (d_number * 65536.0);
65 }
66
67 int _mmstreamrecorder_get_freespace(const gchar *path, guint64 *free_space)
68 {
69         struct statfs fs;
70
71         g_assert(path);
72
73         if (!g_file_test(path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
74                 _mmstreamrec_dbg_log("File(%s) doesn't exist.", path);
75                 return -2;
76         }
77
78         if (-1 == statfs(path, &fs)) {
79                 _mmstreamrec_dbg_log("Getting free space is failed.(%s)", path);
80                 return -1;
81         }
82
83         *free_space = (guint64) fs.f_bsize * fs.f_bavail;
84         return 1;
85 }
86
87 int _mmstreamrecorder_get_file_size(const char *filename, guint64 * size)
88 {
89         struct stat buf;
90
91         if (stat(filename, &buf) != 0)
92                 return -1;
93         *size = (guint64) buf.st_size;
94         return 1;
95 }
96
97 void _mmstreamrecorder_err_trace_write(char *str_filename, char *func_name, int line_num, char *fmt, ...)
98 {
99         FILE *f = NULL;
100         va_list ap = { 0 };
101         char time_string[TIME_STRING_MAX_LEN] = { '\0', };
102
103         time_t current_time;
104         struct tm new_time;
105
106         mmf_return_if_fail(str_filename);
107
108         current_time = time(NULL);
109         localtime_r(&current_time, &new_time);
110
111         f = fopen(str_filename, "a");
112         if (f == NULL) {
113                 _mmstreamrec_dbg_warn("Failed to open file.[%s]", str_filename);
114                 return;
115         }
116
117         asctime_r(&new_time, time_string);
118         fprintf(f, "[%.19s][%05d][%s]", time_string, line_num, func_name);
119
120         va_start(ap, fmt);
121         vfprintf(f, fmt, ap);
122         va_end(ap);
123
124         fprintf(f, "\n");
125
126         fclose(f);
127 }
128
129 int _mmstreamrecorder_get_pixel_format(GstCaps *caps)
130 {
131         const GstStructure *structure;
132         const char *media_type = NULL;
133         MMPixelFormatType type = MM_PIXEL_FORMAT_INVALID;
134         unsigned int fourcc = 0;
135         GstVideoInfo media_info;
136
137         mmf_return_val_if_fail(caps != NULL, MM_PIXEL_FORMAT_INVALID);
138
139         structure = gst_caps_get_structure(caps, 0);
140         media_type = gst_structure_get_name(structure);
141
142         if (media_type == NULL) {
143                 _mmstreamrec_dbg_log("failed to get media_type");
144                 return MM_PIXEL_FORMAT_INVALID;
145         }
146
147         if (!strcmp(media_type, "image/jpeg")) {
148                 _mmstreamrec_dbg_log("It is jpeg.");
149                 type = MM_PIXEL_FORMAT_ENCODED;
150         } else if (!strcmp(media_type, "video/x-raw-yuv")) {
151                 _mmstreamrec_dbg_log("It is yuv.");
152                 gst_video_info_init(&media_info);
153                 if (gst_video_info_from_caps(&media_info, caps)) {
154                         fourcc = gst_video_format_to_fourcc(GST_VIDEO_INFO_FORMAT(&media_info));
155                         type = _mmstreamrecorder_get_pixtype(fourcc);
156                 } else {
157                         _mmstreamrec_dbg_err("Getting media_info is failed");
158                 }
159         } else if (!strcmp(media_type, "video/x-raw-rgb")) {
160                 _mmstreamrec_dbg_log("It is rgb.");
161                 type = MM_PIXEL_FORMAT_RGB888;
162         } else {
163                 _mmstreamrec_dbg_err("Not supported format");
164                 type = MM_PIXEL_FORMAT_INVALID;
165         }
166
167         _mmstreamrec_dbg_log("Type [%d]", type);
168
169 error:
170         gst_caps_unref(caps);
171         caps = NULL;
172
173         return type;
174 }
175
176 unsigned int _mmstreamrecorder_get_fourcc(int pixtype, int codectype, int use_zero_copy_format)
177 {
178         unsigned int fourcc = 0;
179
180         _mmstreamrec_dbg_log("pixtype(%d)", pixtype);
181
182         switch (pixtype) {
183         case MM_PIXEL_FORMAT_NV12:
184                 if (use_zero_copy_format)
185                         fourcc = GST_MAKE_FOURCC('S', 'N', '1', '2');
186                 else
187                         fourcc = GST_MAKE_FOURCC('N', 'V', '1', '2');
188                 break;
189         case MM_PIXEL_FORMAT_YUYV:
190                 if (use_zero_copy_format)
191                         fourcc = GST_MAKE_FOURCC('S', 'U', 'Y', 'V');
192                 else
193                         fourcc = GST_MAKE_FOURCC('Y', 'U', 'Y', '2');
194                 break;
195         case MM_PIXEL_FORMAT_UYVY:
196                 if (use_zero_copy_format)
197                         fourcc = GST_MAKE_FOURCC('S', 'Y', 'V', 'Y');
198                 else
199                         fourcc = GST_MAKE_FOURCC('U', 'Y', 'V', 'Y');
200
201                 break;
202         case MM_PIXEL_FORMAT_I420:
203                 if (use_zero_copy_format)
204                         fourcc = GST_MAKE_FOURCC('S', '4', '2', '0');
205                 else
206                         fourcc = GST_MAKE_FOURCC('I', '4', '2', '0');
207                 break;
208         case MM_PIXEL_FORMAT_YV12:
209                 fourcc = GST_MAKE_FOURCC('Y', 'V', '1', '2');
210                 break;
211         case MM_PIXEL_FORMAT_422P:
212                 fourcc = GST_MAKE_FOURCC('4', '2', '2', 'P');
213                 break;
214         case MM_PIXEL_FORMAT_RGB565:
215                 fourcc = GST_MAKE_FOURCC('R', 'G', 'B', 'P');
216                 break;
217         case MM_PIXEL_FORMAT_RGB888:
218                 fourcc = GST_MAKE_FOURCC('R', 'G', 'B', ' ');
219                 break;
220         case MM_PIXEL_FORMAT_ENCODED:
221                 if (codectype == MM_IMAGE_CODEC_JPEG) {
222                         fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');
223                 } else if (codectype == MM_IMAGE_CODEC_JPEG_SRW) {
224                         fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');   /*TODO: JPEG+SamsungRAW format */
225                 } else if (codectype == MM_IMAGE_CODEC_SRW) {
226                         fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');   /*TODO: SamsungRAW format */
227                 } else if (codectype == MM_IMAGE_CODEC_PNG) {
228                         fourcc = GST_MAKE_FOURCC('P', 'N', 'G', ' ');
229                 } else {
230                         /* Please let us know what other fourcces are. ex) BMP, GIF? */
231                         fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');
232                 }
233                 break;
234         case MM_PIXEL_FORMAT_ITLV_JPEG_UYVY:
235                 fourcc = GST_MAKE_FOURCC('I', 'T', 'L', 'V');
236                 break;
237         default:
238                 _mmstreamrec_dbg_log("Not proper pixel type[%d]. Set default - I420", pixtype);
239                 if (use_zero_copy_format)
240                         fourcc = GST_MAKE_FOURCC('S', '4', '2', '0');
241                 else
242                         fourcc = GST_MAKE_FOURCC('I', '4', '2', '0');
243                 break;
244         }
245
246         return fourcc;
247 }
248
249 int _mmstreamrecorder_get_pixtype(unsigned int fourcc)
250 {
251         int pixtype = MM_PIXEL_FORMAT_INVALID;
252 /*
253         char *pfourcc = (char*)&fourcc;
254         _mmstreamrec_dbg_log("fourcc(%c%c%c%c)", pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
255 */
256         switch (fourcc) {
257         case GST_MAKE_FOURCC('S', 'N', '1', '2'):
258         case GST_MAKE_FOURCC('N', 'V', '1', '2'):
259                 pixtype = MM_PIXEL_FORMAT_NV12;
260                 break;
261         case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
262         case GST_MAKE_FOURCC('Y', 'U', 'Y', 'V'):
263         case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'):
264                 pixtype = MM_PIXEL_FORMAT_YUYV;
265                 break;
266         case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
267         case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
268                 pixtype = MM_PIXEL_FORMAT_UYVY;
269                 break;
270         case GST_MAKE_FOURCC('S', '4', '2', '0'):
271         case GST_MAKE_FOURCC('I', '4', '2', '0'):
272                 pixtype = MM_PIXEL_FORMAT_I420;
273                 break;
274         case GST_MAKE_FOURCC('Y', 'V', '1', '2'):
275                 pixtype = MM_PIXEL_FORMAT_YV12;
276                 break;
277         case GST_MAKE_FOURCC('4', '2', '2', 'P'):
278                 pixtype = MM_PIXEL_FORMAT_422P;
279                 break;
280         case GST_MAKE_FOURCC('R', 'G', 'B', 'P'):
281                 pixtype = MM_PIXEL_FORMAT_RGB565;
282                 break;
283         case GST_MAKE_FOURCC('R', 'G', 'B', '3'):
284                 pixtype = MM_PIXEL_FORMAT_RGB888;
285                 break;
286         case GST_MAKE_FOURCC('A', 'R', 'G', 'B'):
287         case GST_MAKE_FOURCC('x', 'R', 'G', 'B'):
288                 pixtype = MM_PIXEL_FORMAT_ARGB;
289                 break;
290         case GST_MAKE_FOURCC('B', 'G', 'R', 'A'):
291         case GST_MAKE_FOURCC('B', 'G', 'R', 'x'):
292                 pixtype = MM_PIXEL_FORMAT_RGBA;
293                 break;
294         case GST_MAKE_FOURCC('J', 'P', 'E', 'G'):
295         case GST_MAKE_FOURCC('P', 'N', 'G', ' '):
296                 pixtype = MM_PIXEL_FORMAT_ENCODED;
297                 break;
298          /*FIXME*/ case GST_MAKE_FOURCC('I', 'T', 'L', 'V'):
299                 pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
300                 break;
301         default:
302                 _mmstreamrec_dbg_log("Not supported fourcc type(%x)", fourcc);
303                 pixtype = MM_PIXEL_FORMAT_INVALID;
304                 break;
305         }
306
307         return pixtype;
308 }
309
310 guint16 get_language_code(const char *str)
311 {
312         return (guint16) (((str[0] - 0x60) & 0x1F) << 10) + (((str[1] - 0x60) & 0x1F) << 5) + ((str[2] - 0x60) & 0x1F);
313 }
314
315 gchar *str_to_utf8(const gchar * str)
316 {
317         return g_convert(str, -1, "UTF-8", "ASCII", NULL, NULL, NULL);
318 }
319
320 __attribute__ ((gnu_inline)) inline gboolean write_tag(FILE *f, const gchar *tag)
321 {
322         while (*tag)
323                 FPUTC_CHECK(*tag++, f);
324
325         return TRUE;
326 }
327
328 __attribute__ ((gnu_inline)) inline gboolean write_to_32(FILE *f, guint val)
329 {
330         FPUTC_CHECK(val >> 24, f);
331         FPUTC_CHECK(val >> 16, f);
332         FPUTC_CHECK(val >> 8, f);
333         FPUTC_CHECK(val, f);
334         return TRUE;
335 }