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