Fix build error for upgrading toolchain
[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 = 0;
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                 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 if (!strcmp(media_type, "video/x-raw-rgb")) {
157                 _mmstreamrec_dbg_log("It is rgb.");
158                 type = MM_PIXEL_FORMAT_RGB888;
159         } else {
160                 _mmstreamrec_dbg_err("Not supported format");
161                 type = MM_PIXEL_FORMAT_INVALID;
162         }
163
164         _mmstreamrec_dbg_log("Type [%d]", type);
165
166         gst_caps_unref(caps);
167         caps = NULL;
168
169         return type;
170 }
171
172 unsigned int _mmstreamrecorder_get_fourcc(int pixtype, int codectype, int use_zero_copy_format)
173 {
174         unsigned int fourcc = 0;
175
176         _mmstreamrec_dbg_log("pixtype(%d)", pixtype);
177
178         switch (pixtype) {
179         case MM_PIXEL_FORMAT_NV12:
180                 if (use_zero_copy_format)
181                         fourcc = GST_MAKE_FOURCC('S', 'N', '1', '2');
182                 else
183                         fourcc = GST_MAKE_FOURCC('N', 'V', '1', '2');
184                 break;
185         case MM_PIXEL_FORMAT_YUYV:
186                 if (use_zero_copy_format)
187                         fourcc = GST_MAKE_FOURCC('S', 'U', 'Y', 'V');
188                 else
189                         fourcc = GST_MAKE_FOURCC('Y', 'U', 'Y', '2');
190                 break;
191         case MM_PIXEL_FORMAT_UYVY:
192                 if (use_zero_copy_format)
193                         fourcc = GST_MAKE_FOURCC('S', 'Y', 'V', 'Y');
194                 else
195                         fourcc = GST_MAKE_FOURCC('U', 'Y', 'V', 'Y');
196
197                 break;
198         case MM_PIXEL_FORMAT_I420:
199                 if (use_zero_copy_format)
200                         fourcc = GST_MAKE_FOURCC('S', '4', '2', '0');
201                 else
202                         fourcc = GST_MAKE_FOURCC('I', '4', '2', '0');
203                 break;
204         case MM_PIXEL_FORMAT_YV12:
205                 fourcc = GST_MAKE_FOURCC('Y', 'V', '1', '2');
206                 break;
207         case MM_PIXEL_FORMAT_422P:
208                 fourcc = GST_MAKE_FOURCC('4', '2', '2', 'P');
209                 break;
210         case MM_PIXEL_FORMAT_RGB565:
211                 fourcc = GST_MAKE_FOURCC('R', 'G', 'B', 'P');
212                 break;
213         case MM_PIXEL_FORMAT_RGB888:
214                 fourcc = GST_MAKE_FOURCC('R', 'G', 'B', ' ');
215                 break;
216         case MM_PIXEL_FORMAT_ENCODED:
217                 if (codectype == MM_IMAGE_CODEC_JPEG) {
218                         fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');
219                 } else if (codectype == MM_IMAGE_CODEC_JPEG_SRW) {
220                         fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');   /*TODO: JPEG+SamsungRAW format */
221                 } else if (codectype == MM_IMAGE_CODEC_SRW) {
222                         fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');   /*TODO: SamsungRAW format */
223                 } else if (codectype == MM_IMAGE_CODEC_PNG) {
224                         fourcc = GST_MAKE_FOURCC('P', 'N', 'G', ' ');
225                 } else {
226                         /* Please let us know what other fourcces are. ex) BMP, GIF? */
227                         fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');
228                 }
229                 break;
230         case MM_PIXEL_FORMAT_ITLV_JPEG_UYVY:
231                 fourcc = GST_MAKE_FOURCC('I', 'T', 'L', 'V');
232                 break;
233         default:
234                 _mmstreamrec_dbg_log("Not proper pixel type[%d]. Set default - I420", pixtype);
235                 if (use_zero_copy_format)
236                         fourcc = GST_MAKE_FOURCC('S', '4', '2', '0');
237                 else
238                         fourcc = GST_MAKE_FOURCC('I', '4', '2', '0');
239                 break;
240         }
241
242         return fourcc;
243 }
244
245 int _mmstreamrecorder_get_pixtype(unsigned int fourcc)
246 {
247         int pixtype = MM_PIXEL_FORMAT_INVALID;
248 /*
249         char *pfourcc = (char*)&fourcc;
250         _mmstreamrec_dbg_log("fourcc(%c%c%c%c)", pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
251 */
252         switch (fourcc) {
253         case GST_MAKE_FOURCC('S', 'N', '1', '2'):
254         case GST_MAKE_FOURCC('N', 'V', '1', '2'):
255                 pixtype = MM_PIXEL_FORMAT_NV12;
256                 break;
257         case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'):
258         case GST_MAKE_FOURCC('Y', 'U', 'Y', 'V'):
259         case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'):
260                 pixtype = MM_PIXEL_FORMAT_YUYV;
261                 break;
262         case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'):
263         case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'):
264                 pixtype = MM_PIXEL_FORMAT_UYVY;
265                 break;
266         case GST_MAKE_FOURCC('S', '4', '2', '0'):
267         case GST_MAKE_FOURCC('I', '4', '2', '0'):
268                 pixtype = MM_PIXEL_FORMAT_I420;
269                 break;
270         case GST_MAKE_FOURCC('Y', 'V', '1', '2'):
271                 pixtype = MM_PIXEL_FORMAT_YV12;
272                 break;
273         case GST_MAKE_FOURCC('4', '2', '2', 'P'):
274                 pixtype = MM_PIXEL_FORMAT_422P;
275                 break;
276         case GST_MAKE_FOURCC('R', 'G', 'B', 'P'):
277                 pixtype = MM_PIXEL_FORMAT_RGB565;
278                 break;
279         case GST_MAKE_FOURCC('R', 'G', 'B', '3'):
280                 pixtype = MM_PIXEL_FORMAT_RGB888;
281                 break;
282         case GST_MAKE_FOURCC('A', 'R', 'G', 'B'):
283         case GST_MAKE_FOURCC('x', 'R', 'G', 'B'):
284                 pixtype = MM_PIXEL_FORMAT_ARGB;
285                 break;
286         case GST_MAKE_FOURCC('B', 'G', 'R', 'A'):
287         case GST_MAKE_FOURCC('B', 'G', 'R', 'x'):
288                 pixtype = MM_PIXEL_FORMAT_RGBA;
289                 break;
290         case GST_MAKE_FOURCC('J', 'P', 'E', 'G'):
291         case GST_MAKE_FOURCC('P', 'N', 'G', ' '):
292                 pixtype = MM_PIXEL_FORMAT_ENCODED;
293                 break;
294          /*FIXME*/ case GST_MAKE_FOURCC('I', 'T', 'L', 'V'):
295                 pixtype = MM_PIXEL_FORMAT_ITLV_JPEG_UYVY;
296                 break;
297         default:
298                 _mmstreamrec_dbg_log("Not supported fourcc type(%x)", fourcc);
299                 pixtype = MM_PIXEL_FORMAT_INVALID;
300                 break;
301         }
302
303         return pixtype;
304 }
305
306 guint16 get_language_code(const char *str)
307 {
308         return (guint16) (((str[0] - 0x60) & 0x1F) << 10) + (((str[1] - 0x60) & 0x1F) << 5) + ((str[2] - 0x60) & 0x1F);
309 }
310
311 gchar *str_to_utf8(const gchar * str)
312 {
313         return g_convert(str, -1, "UTF-8", "ASCII", NULL, NULL, NULL);
314 }
315
316 __attribute__ ((gnu_inline)) inline gboolean write_tag(FILE *f, const gchar *tag)
317 {
318         while (*tag)
319                 FPUTC_CHECK(*tag++, f);
320
321         return TRUE;
322 }
323
324 __attribute__ ((gnu_inline)) inline gboolean write_to_32(FILE *f, guint val)
325 {
326         FPUTC_CHECK(val >> 24, f);
327         FPUTC_CHECK(val >> 16, f);
328         FPUTC_CHECK(val >> 8, f);
329         FPUTC_CHECK(val, f);
330         return TRUE;
331 }