[libmm-streamrecorder] UTC issue fixes
[platform/core/multimedia/libmm-streamrecorder.git] / src / mm_streamrecorder_ini.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 #include <glib.h>
23 #include <glib/gstdio.h>
24 #include <stdlib.h>
25 #include <iniparser.h>
26 #include <mm_debug.h>
27 #include <mm_error.h>
28 #include "mm_streamrecorder_ini.h"
29
30 static gboolean loaded = FALSE;
31
32 /* global variables here */
33 #ifdef MM_STREAMRECORDER_DEFAULT_INI
34 static gboolean __generate_default_ini(void);
35 #endif
36 static  void    __get_element_list(mm_streamrecorder_ini_t* ini, gchar* str, int keyword_type);
37
38 static void __mm_streamrecorder_ini_check_status(void);
39
40 /* macro */
41 #define MM_STREAMRECORDER_INI_GET_STRING(x_dict, x_item, x_ini, x_default) \
42 do { \
43         gchar *str = NULL; \
44         gint length = 0; \
45         str = iniparser_getstring(x_dict, x_ini, x_default); \
46         if (str) { \
47                 length = strlen(str); \
48                 if ((length > 1) && (length < STREAMRECORDER_INI_MAX_STRLEN)) \
49                         strncpy(x_item, str, length+1); \
50                 else \
51                         strncpy(x_item, x_default, STREAMRECORDER_INI_MAX_STRLEN-1); \
52         } else { \
53                 strncpy(x_item, x_default, STREAMRECORDER_INI_MAX_STRLEN-1); \
54         } \
55 } while (0)
56
57 /* x_ini is the list of value to be set at x_list[index] */
58 #define MMSTREAMRECORDER_INI_GET_INT_FROM_LIST(x_dict, x_list, x_list_max, x_ini, x_default) \
59 do { \
60         int index = 0; \
61         int value = 0; \
62         const char *delimiters = " ,"; \
63         char *usr_ptr = NULL; \
64         char *token = NULL; \
65         gchar temp_arr[STREAMRECORDER_INI_MAX_STRLEN] = {0}; \
66         MM_STREAMRECORDER_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
67         token = strtok_r(temp_arr, delimiters, &usr_ptr); \
68         while (token) { \
69                 if (index > x_list_max -1) { \
70                         debug_error("%d is not valid index\n", index); \
71                         break; \
72                 } else { \
73                         value = atoi(token); \
74                         x_list[index] = value; \
75                         index++; \
76                 } \
77                 token = strtok_r(NULL, delimiters, &usr_ptr); \
78         } \
79 } while (0)
80
81
82 #ifdef MM_STREAMRECORDER_DEFAULT_INI
83 static
84 gboolean __generate_default_ini(void)
85 {
86         FILE *fp = NULL;
87         const gchar *default_ini = MM_STREAMRECORDER_DEFAULT_INI;
88
89         /* create new file */
90         fp = fopen(MM_STREAMRECORDER_INI_DEFAULT_PATH, "wt");
91
92         if (!fp)
93                 return FALSE;
94
95         /* writing default ini file */
96         if (strlen(default_ini) != fwrite(default_ini, 1, strlen(default_ini), fp)) {
97                 fclose(fp);
98                 return FALSE;
99         }
100
101         fclose(fp);
102         return TRUE;
103 }
104 #endif
105
106 int _mm_streamrecorder_ini_load(mm_streamrecorder_ini_t *ini)
107 {
108         dictionary *dict = NULL;
109
110         debug_fenter();
111
112         __mm_streamrecorder_ini_check_status();
113
114         /* first, try to load existing ini file */
115         dict = iniparser_load(MM_STREAMRECORDER_INI_DEFAULT_PATH);
116
117         /* if no file exists. create one with set of default values */
118         if (!dict) {
119                 _mmstreamrec_dbg_err("No ini file found. \n");
120                 return MM_ERROR_FILE_NOT_FOUND;
121         }
122
123         /* get ini values */
124         memset(ini, 0, sizeof(mm_streamrecorder_ini_t));
125
126         if (dict) {                                     /* if dict is available */
127                 /* general */
128                 ini->encsink_src_islive = iniparser_getboolean(dict, "general:encscink source is live", DEFAULT_ENCSINK_SRC_IS_LIVE);
129                 ini->retrial_count = iniparser_getint(dict, "general:retrialcount", DEFAULT_RETRIAL_COUNT);
130                 ini->minimum_frame = iniparser_getint(dict, "general:minimum frame", DEFAULT_MINIMUM_FRAME);
131                 ini->convert_output_buffer_num = iniparser_getint(dict, "general:convert output buffer num", DEFAULT_CONVERT_OUTPUT_BUFFER_NUM);
132                 ini->reset_pause_time = iniparser_getint(dict, "general:reset pause time", DEFAULT_RESET_PAUSE_TIME);
133                 ini->screen_record = iniparser_getint(dict, "general:screen record", DEFAULT_SCREEN_RECORD);
134
135                 /*encodebin */
136                 ini->encsink_bin_profile = iniparser_getint(dict, "encodebin:encsink bin profile", DEFAULT_ENCSINK_BIN_PROFILE);
137                 ini->encsink_bin_auto_audio_resample = iniparser_getboolean(dict, "encodebin:encsink bin auto audio resample", DEFAULT_ENCSINK_BIN_AUTO_AUDIO_RESAMPLE);
138                 ini->encsink_bin_auto_colorspace = iniparser_getboolean(dict, "encodebin: encsink bin auto colorspace", DEFAULT_ENCSINK_BIN_AUTO_COLORSPACE);
139                 ini->encsink_bin_use_video_toggle = iniparser_getboolean(dict, "encodebin:encsink bin use video toggle", DEFAULT_ENCSINK_BIN_USE_VIDEO_TOGGLE);
140                 ini->encsink_bin_auto_audio_convert = iniparser_getboolean(dict, "encodebin:encsink bin auto audio convert", DEFAULT_ENCSINK_BIN_AUTO_CONVERT);
141
142                 /* pipeline */
143                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_src, (const char *)"pipeline:encsink bin source", (char *)DEFAULT_VIDEO_SOURCE);
144                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_audio_src, (const char *)"pipeline:name of audio src", (char *)DEFAULT_AUDIO_SRC);
145                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->h264_video_encoder, (const char *)"pipeline:h264 encoder", (char *)DEFAULT_NAME_OF_H264_VIDEO_ENCODER);
146                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->h263_video_encoder, (const char *)"pipeline:h263 encoder", (char *)DEFAULT_NAME_OF_H263_VIDEO_ENCODER);
147                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->mpeg4_video_encoder, (const char *)"pipeline:mpeg4 encoder", (char *)DEFAULT_NAME_OF_MPEG4_VIDEO_ENCODER);
148                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_bin_audio_encoder, (const char *)"pipeline:name of audio encoder", (char *)DEFAULT_NAME_OF_AUDIO_ENCODER);
149                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->encsink_bin_use_parser, (const char *)"pipeline:use parser", (char *)DEFAULT_USE_PARSER);
150                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_bin_video_converter, (const char *)"pipeline:name of video converter", (char *)DEFAULT_NAME_OF_VIDEO_CONVERTER);
151                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_bin_3GPMUXER, (const char *)"pipeline:name of 3GP muxer", (char *)DEFAULT_NAME_OF_3GP_MUXER);
152                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_bin_MP4MUXER, (const char *)"pipeline:name of MP4 muxer", (char *)DEFAULT_NAME_OF_MP4_MUXER);
153                 MM_STREAMRECORDER_INI_GET_STRING(dict, ini->name_of_encsink_sink, (const char *)"pipeline:name of sink", (char *)DEFAULT_NAME_OF_BIN_SINK);
154
155                 /* audio parameter */
156                 ini->audio_frame_minimum_space = iniparser_getint(dict, "audio param:audio frame minimum space", DEFAULT_AUDIO_FRAME_MINIMUM_SPACE);
157                 ini->audio_frame_wait_time = iniparser_getint(dict, "audio param:audio frame wait time", DEFAULT_AUDIO_FRAME_WAIT_TIME);
158
159                 /* video parameter */
160                 ini->video_frame_wait_time = iniparser_getint(dict, "video param:video frame wait time", DEFAULT_VIDEO_FRAME_WAIT_TIME);
161
162                 /*supported attribute*/
163                  MMSTREAMRECORDER_INI_GET_INT_FROM_LIST(dict, ini->supported_video_width, STREAMRECORDER_ATTRIBUTE_NUM_MAX, "attribute:supported width", DEFAULT_SUPPORTED_WIDTH);
164                 MMSTREAMRECORDER_INI_GET_INT_FROM_LIST(dict, ini->supported_video_height, STREAMRECORDER_ATTRIBUTE_NUM_MAX, "attribute:supported height", DEFAULT_SUPPORTED_HEIGHT);
165                 __get_element_list(ini, iniparser_getstring(dict, "attribute:supported audio encoders", DEFAULT_SUPPORTED_AUDIO_ENCODERS), KEYWORD_AUDIO_ENCODERS);
166                 __get_element_list(ini, iniparser_getstring(dict, "attribute:supported video encoders", DEFAULT_SUPPORTED_VIDEO_ENCODERS), KEYWORD_VIDEO_ENCODERS);
167                 __get_element_list(ini, iniparser_getstring(dict, "attribute:supported file formats", DEFAULT_SUPPORTED_FILE_FORMATS), KEYWORD_FILE_FORMATS);
168
169         } else {                                        /* if dict is not available just fill the structure with default value */
170                 _mmstreamrec_dbg_err("failed to load ini. using hardcoded default\n");
171                 /* general */
172                 ini->encsink_src_islive = DEFAULT_ENCSINK_SRC_IS_LIVE;
173                 ini->retrial_count = DEFAULT_RETRIAL_COUNT;
174                 ini->minimum_frame = DEFAULT_MINIMUM_FRAME;
175                 ini->convert_output_buffer_num = DEFAULT_CONVERT_OUTPUT_BUFFER_NUM;
176                 ini->reset_pause_time = DEFAULT_RESET_PAUSE_TIME;
177                 ini->screen_record = DEFAULT_SCREEN_RECORD;
178
179                 /*encodebin */
180                 ini->encsink_bin_profile = DEFAULT_ENCSINK_BIN_PROFILE;
181                 ini->encsink_bin_auto_audio_resample = DEFAULT_ENCSINK_BIN_AUTO_AUDIO_RESAMPLE;
182                 ini->encsink_bin_auto_colorspace = DEFAULT_ENCSINK_BIN_AUTO_COLORSPACE;
183                 ini->encsink_bin_use_video_toggle = DEFAULT_ENCSINK_BIN_USE_VIDEO_TOGGLE;
184                 ini->encsink_bin_auto_audio_convert = DEFAULT_ENCSINK_BIN_AUTO_CONVERT;
185
186                 /* pipeline */
187                 strncpy(ini->name_of_encsink_src, DEFAULT_VIDEO_SOURCE, STREAMRECORDER_INI_MAX_STRLEN - 1);
188                 strncpy(ini->name_of_audio_src, DEFAULT_AUDIO_SRC, STREAMRECORDER_INI_MAX_STRLEN - 1);
189                 strncpy(ini->h264_video_encoder, DEFAULT_NAME_OF_H264_VIDEO_ENCODER, STREAMRECORDER_INI_MAX_STRLEN - 1);
190                 strncpy(ini->h263_video_encoder, DEFAULT_NAME_OF_H263_VIDEO_ENCODER, STREAMRECORDER_INI_MAX_STRLEN - 1);
191                 strncpy(ini->mpeg4_video_encoder, DEFAULT_NAME_OF_MPEG4_VIDEO_ENCODER, STREAMRECORDER_INI_MAX_STRLEN - 1);
192                 strncpy(ini->name_of_encsink_bin_audio_encoder, DEFAULT_NAME_OF_AUDIO_ENCODER, STREAMRECORDER_INI_MAX_STRLEN - 1);
193                 strncpy(ini->encsink_bin_use_parser, DEFAULT_USE_PARSER, STREAMRECORDER_INI_MAX_STRLEN - 1);
194                 strncpy(ini->name_of_encsink_bin_video_converter, DEFAULT_NAME_OF_VIDEO_CONVERTER, STREAMRECORDER_INI_MAX_STRLEN - 1);
195                 strncpy(ini->name_of_encsink_bin_3GPMUXER, DEFAULT_NAME_OF_3GP_MUXER, STREAMRECORDER_INI_MAX_STRLEN - 1);
196                 strncpy(ini->name_of_encsink_bin_MP4MUXER, DEFAULT_NAME_OF_MP4_MUXER, STREAMRECORDER_INI_MAX_STRLEN - 1);
197                 strncpy(ini->name_of_encsink_sink, DEFAULT_NAME_OF_BIN_SINK, STREAMRECORDER_INI_MAX_STRLEN - 1);
198
199                 /* audio parameter */
200                 ini->audio_frame_minimum_space = DEFAULT_AUDIO_FRAME_MINIMUM_SPACE;
201                 ini->audio_frame_wait_time = DEFAULT_AUDIO_FRAME_WAIT_TIME;
202
203                 /* video parameter */
204                 ini->video_frame_wait_time = DEFAULT_VIDEO_FRAME_WAIT_TIME;
205
206                 /*supported attributes*/
207                 __get_element_list(ini, DEFAULT_SUPPORTED_AUDIO_ENCODERS, KEYWORD_AUDIO_ENCODERS);
208                 __get_element_list(ini, DEFAULT_SUPPORTED_VIDEO_ENCODERS, KEYWORD_VIDEO_ENCODERS);
209                 __get_element_list(ini, DEFAULT_SUPPORTED_FILE_FORMATS, KEYWORD_FILE_FORMATS);
210         }
211
212         /* free dict as we got our own structure */
213         iniparser_freedict(dict);
214
215         /* dump structure */
216         _mmstreamrec_dbg_log("[Stream Recorder initial setting][Start]");
217
218         /* general */
219         _mmstreamrec_dbg_log("encsink_src_islive : %d", ini->encsink_src_islive);
220         _mmstreamrec_dbg_log("retrial_count : %d", ini->retrial_count);
221         _mmstreamrec_dbg_log("minimum_frame : %d", ini->minimum_frame);
222         _mmstreamrec_dbg_log("convert_output_buffer_num : %d", ini->convert_output_buffer_num);
223         _mmstreamrec_dbg_log("reset_pause_time : %d", ini->reset_pause_time);
224         _mmstreamrec_dbg_log("screen_record : %d", ini->screen_record);
225
226         /*encodebin */
227         _mmstreamrec_dbg_log("encode bin profile : %d", ini->encsink_bin_profile);
228         _mmstreamrec_dbg_log("encode bin auto audio resample property  : %d", ini->encsink_bin_auto_audio_resample);
229         _mmstreamrec_dbg_log("encode bin auto colorspace property : %d", ini->encsink_bin_auto_colorspace);
230         _mmstreamrec_dbg_log("encode bin use video toggle property : %d", ini->encsink_bin_use_video_toggle);
231         _mmstreamrec_dbg_log("encode bin auto audio convert property : %d", ini->encsink_bin_auto_audio_convert);
232
233         /* pipeline */
234         _mmstreamrec_dbg_log("name_of_encodebin_source : %s", ini->name_of_encsink_src);
235         _mmstreamrec_dbg_log("name_of_audio_source : %s", ini->name_of_audio_src);
236         _mmstreamrec_dbg_log("name_of_h264_video_encoder : %s", ini->h264_video_encoder);
237         _mmstreamrec_dbg_log("name_of_h263_video_encoder : %s", ini->h263_video_encoder);
238         _mmstreamrec_dbg_log("name_of_mpeg4_video_encoder : %s", ini->mpeg4_video_encoder);
239         _mmstreamrec_dbg_log("name_of_audio_encoder : %s", ini->name_of_encsink_bin_audio_encoder);
240         _mmstreamrec_dbg_log("name_of_video_converter : %s", ini->name_of_encsink_bin_video_converter);
241         _mmstreamrec_dbg_log("name_of_3GP_muxer : %s", ini->name_of_encsink_bin_3GPMUXER);
242         _mmstreamrec_dbg_log("name_of_MP4_muxer : %s", ini->name_of_encsink_bin_MP4MUXER);
243         _mmstreamrec_dbg_log("name_of_sink : %s", ini->name_of_encsink_sink);
244
245         /* audio parameter */
246         _mmstreamrec_dbg_log("audio_frame_minimum_space : %d", ini->audio_frame_minimum_space);
247         _mmstreamrec_dbg_log("audio_frame_wait_time : %d", ini->audio_frame_wait_time);
248
249         /* video parameter */
250         _mmstreamrec_dbg_log("video_frame_wait_time : %d", ini->video_frame_wait_time);
251
252         _mmstreamrec_dbg_log("[Stream Recorder initial setting][End]");
253
254         loaded = TRUE;
255
256         debug_fleave();
257
258         return MM_ERROR_NONE;
259 }
260
261 static
262 void    __get_element_list(mm_streamrecorder_ini_t* ini, gchar* str, int keyword_type)
263 {
264         gchar** list = NULL;
265         gchar** walk = NULL;
266         int i = 0;
267         gchar* strtmp = NULL;
268
269         if (!str)
270                 return;
271
272         if (strlen(str) < 1)
273                 return;
274
275         strtmp = g_strdup(str);
276
277         /* trimming. it works inplace */
278         g_strstrip(strtmp);
279
280
281         /* split */
282         list = g_strsplit(strtmp, ",", 10);
283
284         if (!list) {
285                 if (strtmp)
286                         g_free(strtmp);
287
288                 return;
289         }
290
291         /* copy list */
292         switch (keyword_type) {
293         case KEYWORD_AUDIO_ENCODERS:
294         {
295                 for (walk = list; *walk; walk++) {
296                         strncpy(ini->supported_audio_encoders[i], *walk, (STREAMRECORDER_INI_MAX_STRLEN - 1));
297                         g_strstrip(ini->supported_audio_encoders[i]);
298                         ini->supported_audio_encoders[i][STREAMRECORDER_INI_MAX_STRLEN -1] = '\0';
299                         i++;
300                 }
301                 /* mark last item to NULL*/
302                 ini->supported_audio_encoders[i][0] = '\0';
303                 break;
304         }
305         case KEYWORD_VIDEO_ENCODERS:
306         {
307                 for (walk = list; *walk; walk++) {
308                         strncpy(ini->supported_video_encoders[i], *walk, (STREAMRECORDER_INI_MAX_STRLEN - 1));
309                         g_strstrip(ini->supported_video_encoders[i]);
310                         ini->supported_video_encoders[i][STREAMRECORDER_INI_MAX_STRLEN -1] = '\0';
311                         i++;
312                 }
313                 /* mark last item to NULL */
314                 ini->supported_video_encoders[i][0] = '\0';
315                 break;
316         }
317         case KEYWORD_FILE_FORMATS:
318         {
319                 for (walk = list; *walk; walk++) {
320                         strncpy(ini->supported_file_formats[i], *walk, (STREAMRECORDER_INI_MAX_STRLEN - 1));
321                         g_strstrip(ini->supported_file_formats[i]);
322                         ini->supported_file_formats[i][STREAMRECORDER_INI_MAX_STRLEN -1] = '\0';
323                         i++;
324                 }
325                 /* mark last item to NULL*/
326                 ini->supported_file_formats[i][0] = '\0';
327                 break;
328         }
329         default:
330         break;
331         }
332
333         g_strfreev(list);
334         if (strtmp)
335                 g_free(strtmp);
336 }
337
338
339 static
340 void __mm_streamrecorder_ini_check_status(void)
341 {
342         struct stat ini_buff;
343
344         debug_fenter();
345
346         if (g_stat(MM_STREAMRECORDER_INI_DEFAULT_PATH, &ini_buff) < 0) {
347                 _mmstreamrec_dbg_err("failed to get mmfw_wfd_sink ini status\n");
348         } else {
349                 if (ini_buff.st_size < 5) {
350                         _mmstreamrec_dbg_err("mmfw_wfd_sink.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size);
351                         g_remove(MM_STREAMRECORDER_INI_DEFAULT_PATH);
352                 }
353         }
354
355         debug_fleave();
356 }
357
358 int _mm_streamrecorder_ini_unload(mm_streamrecorder_ini_t *ini)
359 {
360         debug_fenter();
361
362         loaded = FALSE;
363
364         debug_fleave();
365
366         return MM_ERROR_NONE;
367 }