2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef __MEDIA_CODEC_INI_C__
18 #define __MEDIA_CODEC_INI_C__
23 #include <glib/gstdio.h>
26 #include <iniparser.h>
27 #include <media_codec_ini.h>
28 #include <media_codec_port.h>
30 #define DEFAULT_VALUE ""
32 #define DEFAULT_HW_DECODER_NAME ""
33 #define DEFAULT_HW_DECODER_MIME ""
34 #define DEFAULT_HW_DECODER_FORMAT ""
36 #define DEFAULT_HW_ENCODER_NAME ""
37 #define DEFAULT_HW_ENCODER_MIME ""
38 #define DEFAULT_HW_ENCODER_FORMAT ""
39 #define DEFAULT_HW_ENCODER_PROPERTY_BITRATE_NAME "bitrate"
41 #define DEFAULT_SW_DECODER_NAME ""
42 #define DEFAULT_SW_DECODER_MIME ""
43 #define DEFAULT_SW_DECODER_FORMAT ""
45 #define DEFAULT_SW_ENCODER_NAME ""
46 #define DEFAULT_SW_ENCODER_MIME ""
47 #define DEFAULT_SW_ENCODER_FORMAT ""
48 #define DEFAULT_SW_ENCODER_PROPERTY_BITRATE_NAME "bitrate"
51 #define CNAME_SIZE 512
53 static codec_list_t general_codec_list[] = {
54 {"h261", MEDIACODEC_H261},
55 {"h263", MEDIACODEC_H263},
56 {"h264", MEDIACODEC_H264},
57 {"mjpeg", MEDIACODEC_MJPEG},
58 {"mpeg1", MEDIACODEC_MPEG1},
59 {"mpeg2", MEDIACODEC_MPEG2},
60 {"mpeg4", MEDIACODEC_MPEG4},
61 {"hevc", MEDIACODEC_HEVC},
62 {"vp8", MEDIACODEC_VP8},
63 {"vp9", MEDIACODEC_VP9},
64 {"vc1", MEDIACODEC_VC1},
65 {"aac_lc", MEDIACODEC_AAC_LC},
66 {"aac_he", MEDIACODEC_AAC_HE},
67 {"aac_he_ps", MEDIACODEC_AAC_HE_PS},
68 {"mp3", MEDIACODEC_MP3},
69 {"amr_nb", MEDIACODEC_AMR_NB},
70 {"amr_wb", MEDIACODEC_AMR_WB},
71 {"vorbis", MEDIACODEC_VORBIS},
72 {"flac", MEDIACODEC_FLAC},
73 {"wmav1", MEDIACODEC_WMAV1},
74 {"wmav2", MEDIACODEC_WMAV2},
75 {"wmapro", MEDIACODEC_WMAPRO},
76 {"opus", MEDIACODEC_OPUS},
79 /* internal functions, macros here */
80 #ifdef MEDIA_CODEC_DEFAULT_INI
81 static gboolean _generate_default_ini(void);
84 static void _mc_ini_check_ini_status(void);
87 #define MEDIA_CODEC_INI_GET_STRING(x_dict, x_item, x_ini, x_default) \
89 const char *str = iniparser_getstring(x_dict, x_ini, x_default); \
91 (strlen(str) > 0) && \
92 (strlen(str) < MEDIA_CODEC_INI_MAX_STRLEN)) \
93 strncpy(x_item, str, MEDIA_CODEC_INI_MAX_STRLEN - 1); \
95 strncpy(x_item, x_default, MEDIA_CODEC_INI_MAX_STRLEN - 1); \
98 #define MEDIA_CODEC_INI_GET_STRING_FROM_LIST(x_dict, x_list, x_ini, x_default) \
100 char *token = NULL; \
101 char *usr_ptr = NULL; \
103 const char *delimiters = " ,"; \
104 gchar temp_arr[MEDIA_CODEC_INI_MAX_STRLEN] = {0}; \
105 MEDIA_CODEC_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
106 strncpy(x_list.property.bitrate_name, DEFAULT_HW_ENCODER_PROPERTY_BITRATE_NAME, MEDIA_CODEC_INI_STRLEN - 1); \
107 token = strtok_r(temp_arr, delimiters, &usr_ptr); \
109 LOGI("index[%d], token[%s]", index, token);\
111 case MEDIA_CODEC_INFO_NAME: \
112 strncpy(x_list.name, token, MEDIA_CODEC_INI_STRLEN - 1); \
114 case MEDIA_CODEC_INFO_MIME: \
115 strncpy(x_list.mime, token, MEDIA_CODEC_INI_STRLEN - 1); \
117 case MEDIA_CODEC_INFO_FORMAT: \
118 strncpy(x_list.format, token, MEDIA_CODEC_INI_STRLEN - 1); \
120 case MEDIA_CODEC_INFO_PROPERTY_BITRATE_NAME: \
121 strncpy(x_list.property.bitrate_name, token, MEDIA_CODEC_INI_STRLEN - 1); \
124 if (x_list.property.ext_num < MEDIA_CODEC_MAX_PROPERTY_EXT) { \
125 strncpy(x_list.property.ext_name[x_list.property.ext_num], token, MEDIA_CODEC_INI_STRLEN - 1); \
126 token = strtok_r(NULL, delimiters, &usr_ptr); \
127 LOGI(" token[property value:%s]", token);\
128 strncpy(x_list.property.ext_value[x_list.property.ext_num], token, MEDIA_CODEC_INI_STRLEN - 1); \
129 x_list.property.ext_num++; \
131 LOGW("unhandled token[%s] from ini", token); \
136 token = strtok_r(NULL, delimiters, &usr_ptr); \
140 #define MEDIA_CODEC_INI_GET_COLOR(x_dict, x_item, x_ini, x_default) \
142 const char *str = iniparser_getstring(x_dict, x_ini, x_default); \
145 (strlen(str) > 0) && \
146 (strlen(str) < MEDIA_CODEC_INI_MAX_STRLEN)) \
147 x_item = (guint) strtoul(str, NULL, 16); \
149 x_item = (guint) strtoul(x_default, NULL, 16); \
152 /* x_ini is the list of index to set TRUE at x_list[index] */
153 #define MEDIA_CODEC_INI_GET_BOOLEAN_FROM_LIST(x_dict, x_list, x_list_max, x_ini, x_default) \
156 const char *delimiters = " ,"; \
157 char *usr_ptr = NULL; \
158 char *token = NULL; \
159 gchar temp_arr[MEDIA_CODEC_INI_MAX_STRLEN] = {0}; \
160 MEDIA_CODEC_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
161 token = strtok_r(temp_arr, delimiters, &usr_ptr); \
163 index = atoi(token); \
164 if (index < 0 || index > x_list_max -1) \
165 LOGW("%d is not valid index\n", index); \
167 x_list[index] = TRUE; \
168 token = strtok_r(NULL, delimiters, &usr_ptr); \
172 /* x_ini is the list of value to be set at x_list[index] */
173 #define MEDIA_CODEC_INI_GET_INT_FROM_LIST(x_dict, x_list, x_list_max, x_ini, x_default) \
177 const char *delimiters = " ,"; \
178 char *usr_ptr = NULL; \
179 char *token = NULL; \
180 gchar temp_arr[MEDIA_CODEC_INI_MAX_STRLEN] = {0}; \
181 MEDIA_CODEC_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
182 token = strtok_r(temp_arr, delimiters, &usr_ptr); \
184 if (index > x_list_max -1) {\
185 LOGE("%d is not valid index\n", index); \
189 value = atoi(token); \
190 x_list[index] = value; \
193 token = strtok_r(NULL, delimiters, &usr_ptr); \
197 #define MEDIA_CODEC_GET_DEFAULT_LIST(x_list, x_default) \
199 strncpy(x_list, x_default, MEDIA_CODEC_INI_STRLEN - 1);\
202 #define MEDIA_CODEC_PRINT_LIST(x_list, x_message) \
205 LOGW("%s =", x_message);\
206 LOGW(" %s %s %s", x_list.name, x_list.mime, x_list.format);\
207 LOGW(" bitrate property: %s\n", x_list.property.bitrate_name);\
208 for (prop_index = 0 ; prop_index < x_list.property.ext_num ; prop_index++)\
209 LOGW(" property ext: %s,%s", x_list.property.ext_name[prop_index], x_list.property.ext_value[prop_index]);\
212 media_format_mimetype_e _mc_convert_media_format_str_to_int(char *sformat)
215 media_format_mimetype_e iformat = MEDIA_FORMAT_I420;
216 if (!strcmp(sformat, "I420")) {
217 iformat = MEDIA_FORMAT_I420;
219 } else if (!strcmp(sformat, "NV12")) {
220 iformat = MEDIA_FORMAT_NV12;
222 } else if (!strcmp(sformat, "NV12T")) {
223 iformat = MEDIA_FORMAT_NV12T;
225 } else if (!strcmp(sformat, "YV12")) {
226 iformat = MEDIA_FORMAT_YV12;
228 } else if (!strcmp(sformat, "NV21")) {
229 iformat = MEDIA_FORMAT_NV21;
231 } else if (!strcmp(sformat, "NV16")) {
232 iformat = MEDIA_FORMAT_NV16;
233 } else if (!strcmp(sformat, "YUYV")) {
234 iformat = MEDIA_FORMAT_YUYV;
236 } else if (!strcmp(sformat, "UYVY")) {
237 iformat = MEDIA_FORMAT_UYVY;
239 } else if (!strcmp(sformat, "422P")) {
240 iformat = MEDIA_FORMAT_422P;
242 } else if (!strcmp(sformat, "RGB565")) {
243 iformat = MEDIA_FORMAT_RGB565;
245 } else if (!strcmp(sformat, "RGB888")) {
246 iformat = MEDIA_FORMAT_RGB888;
248 } else if (!strcmp(sformat, "RGBA")) {
249 iformat = MEDIA_FORMAT_RGBA;
251 } else if (!strcmp(sformat, "ARGB")) {
252 iformat = MEDIA_FORMAT_ARGB;
254 } else if (!strcmp(sformat, "PCM")) {
255 iformat = MEDIA_FORMAT_PCM;
257 } else if (!strcmp(sformat, "PCM_F32LE")) {
258 iformat = MEDIA_FORMAT_PCM_F32LE;
260 } else if (!strcmp(sformat, "H261")) {
261 iformat = MEDIA_FORMAT_H261;
263 } else if (!strcmp(sformat, "H263")) {
264 iformat = MEDIA_FORMAT_H263;
266 } else if (!strcmp(sformat, "H263P")) {
267 iformat = MEDIA_FORMAT_H263P;
269 } else if (!strcmp(sformat, "H264_SP")) {
270 iformat = MEDIA_FORMAT_H264_SP;
272 } else if (!strcmp(sformat, "H264_MP")) {
273 iformat = MEDIA_FORMAT_H264_MP;
275 } else if (!strcmp(sformat, "H264_HP")) {
276 iformat = MEDIA_FORMAT_H264_HP;
278 } else if (!strcmp(sformat, "MPEG4_SP")) {
279 iformat = MEDIA_FORMAT_MPEG4_SP;
281 } else if (!strcmp(sformat, "MPEG4_ASP")) {
282 iformat = MEDIA_FORMAT_MPEG4_ASP;
284 } else if (!strcmp(sformat, "AMR_NB")) {
285 iformat = MEDIA_FORMAT_AMR_NB;
287 } else if (!strcmp(sformat, "AMR_WB")) {
288 iformat = MEDIA_FORMAT_AMR_WB;
290 } else if (!strcmp(sformat, "AAC_LC")) {
291 iformat = MEDIA_FORMAT_AAC_LC;
293 } else if (!strcmp(sformat, "AAC_HE")) {
294 iformat = MEDIA_FORMAT_AAC_HE;
296 } else if (!strcmp(sformat, "AAC_HE_PS")) {
297 iformat = MEDIA_FORMAT_AAC_HE_PS;
299 } else if (!strcmp(sformat, "MP3")) {
300 iformat = MEDIA_FORMAT_MP3;
302 } else if (!strcmp(sformat, "VORBIS")) {
303 iformat = MEDIA_FORMAT_VORBIS;
305 } else if (!strcmp(sformat, "FLAC")) {
306 iformat = MEDIA_FORMAT_FLAC;
308 } else if (!strcmp(sformat, "WMAV1")) {
309 iformat = MEDIA_FORMAT_WMAV1;
311 } else if (!strcmp(sformat, "WMAV2")) {
312 iformat = MEDIA_FORMAT_WMAV2;
314 } else if (!strcmp(sformat, "WMAPRO")) {
315 iformat = MEDIA_FORMAT_WMAPRO;
317 } else if (!strcmp(sformat, "OPUS")) {
318 iformat = MEDIA_FORMAT_OPUS;
323 LOGD("sformat : %x", iformat);
327 int mc_ini_load(mc_ini_t *ini)
329 gchar cname[CNAME_SIZE];
331 dictionary *dict = NULL;
334 memset(ini, 0, sizeof(mc_ini_t));
336 ini->codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]);
338 _mc_ini_check_ini_status();
340 /* first, try to load existing ini file */
341 dict = iniparser_load(MEDIA_CODEC_INI_DEFAULT_PATH);
343 /* if no file exists. create one with set of default values */
345 #ifdef MEDIA_CODEC_DEFAULT_INI
346 LOGD("No inifile found. codec will create default inifile.\n");
347 if (FALSE == _generate_default_ini()) {
348 LOGW("Creating default inifile failed. Media Codec will use default values.\n");
350 /* load default ini */
351 dict = iniparser_load(MEDIA_CODEC_INI_DEFAULT_PATH);
354 LOGD("No ini file found. \n");
355 return LOGERROR_FILE_NOT_FOUND;
360 if (dict) {/* if dict is available */
362 MEDIA_CODEC_INI_GET_STRING(dict, ini->port_name, "port_in_use:media_codec_port", DEFAULT_PORT);
364 for (i = 0; i < ini->codec_list; i++) {
365 memset(cname, 0x00, CNAME_SIZE);
366 snprintf(cname, CNAME_SIZE, "%s", general_codec_list[i].cname);
367 int len = strlen(cname);
368 ini->codec[i].codec_id = general_codec_list[i].ctype;
369 snprintf(cname+len, CNAME_SIZE - len, "%s", ":hw_decoder");
370 MEDIA_CODEC_INI_GET_STRING_FROM_LIST(dict, ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_DECODER], cname, DEFAULT_VALUE);
371 snprintf(cname+len, CNAME_SIZE - len, "%s", ":hw_encoder");
372 MEDIA_CODEC_INI_GET_STRING_FROM_LIST(dict, ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER], cname, DEFAULT_VALUE);
373 snprintf(cname+len, CNAME_SIZE - len, "%s", ":sw_decoder");
374 MEDIA_CODEC_INI_GET_STRING_FROM_LIST(dict, ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_DECODER], cname, DEFAULT_VALUE);
375 snprintf(cname+len, CNAME_SIZE - len, "%s", ":sw_encoder");
376 MEDIA_CODEC_INI_GET_STRING_FROM_LIST(dict, ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER], cname, DEFAULT_VALUE);
378 } else {/* if dict is not available just fill the structure with default value */
380 LOGW("failed to load ini. using hardcoded default\n");
382 snprintf(ini->port_name, sizeof(ini->port_name), "%s", DEFAULT_PORT);
383 for (i = 0; i < ini->codec_list; i++) {
384 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].name, DEFAULT_HW_DECODER_NAME);
385 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].mime, DEFAULT_HW_DECODER_MIME);
386 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].format, DEFAULT_HW_DECODER_FORMAT);
388 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].name, DEFAULT_HW_ENCODER_NAME);
389 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].mime, DEFAULT_HW_ENCODER_MIME);
390 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].format, DEFAULT_HW_ENCODER_FORMAT);
391 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].property.bitrate_name, DEFAULT_HW_ENCODER_PROPERTY_BITRATE_NAME);
393 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].name, DEFAULT_SW_DECODER_NAME);
394 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].mime, DEFAULT_SW_DECODER_MIME);
395 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].format, DEFAULT_SW_DECODER_FORMAT);
397 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].name, DEFAULT_SW_ENCODER_NAME);
398 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].mime, DEFAULT_SW_ENCODER_MIME);
399 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].format, DEFAULT_SW_ENCODER_FORMAT);
400 MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].property.bitrate_name, DEFAULT_SW_ENCODER_PROPERTY_BITRATE_NAME);
404 if (0 == strcmp(ini->port_name, "GST_PORT"))
405 ini->port_type = GST_PORT;
407 LOGE("Invalid port is set to [%s] [%d]\n", ini->port_name, ini->port_type);
408 iniparser_freedict(dict);
411 LOGD("The port is set to [%s] [%d]\n", ini->port_name, ini->port_type);
413 for (i = 0; i < ini->codec_list; i++) {
414 memset(cname, 0x00, CNAME_SIZE);
415 snprintf(cname, CNAME_SIZE, "%s", general_codec_list[i].cname);
416 int len = strlen(cname);
418 snprintf(cname+len, CNAME_SIZE-len, "%s", ":hw_decoder");
419 MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_DECODER], cname);
420 snprintf(cname+len, CNAME_SIZE-len, "%s", ":hw_encoder");
421 MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER], cname);
422 snprintf(cname+len, CNAME_SIZE-len, "%s", ":sw_decoder");
423 MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_DECODER], cname);
424 snprintf(cname+len, CNAME_SIZE-len, "%s", ":sw_encoder");
425 MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER], cname);
428 /* free dict as we got our own structure */
429 iniparser_freedict(dict);
432 LOGD("codec settings -----------------------------------\n");
435 LOGD("port_name: %s\n", ini->port_name);
436 LOGD("port_type : %d\n", ini->port_type);
438 return MC_ERROR_NONE;
440 return MC_COURRPTED_INI;
444 static void _mc_ini_check_ini_status(void)
446 struct stat ini_buff;
448 if (g_stat(MEDIA_CODEC_INI_DEFAULT_PATH, &ini_buff) < 0) {
449 LOGW("failed to get codec ini status\n");
451 if (ini_buff.st_size < 5) {
452 LOGW("codec.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size);
454 if (g_remove(MEDIA_CODEC_INI_DEFAULT_PATH) == -1)
455 LOGE("failed to delete corrupted ini");
460 #ifdef MEDIA_CODEC_DEFAULT_INI
461 static gboolean _generate_default_ini(void)
464 gchar *default_ini = MEDIA_CODEC_DEFAULT_INI;
466 /* create new file */
467 fp = fopen(MEDIA_CODEC_INI_DEFAULT_PATH, "wt");
472 /* writing default ini file */
473 if (strlen(default_ini) !=
474 fwrite(default_ini, 1, strlen(default_ini), fp)) {
483 #endif /* #ifdef _MEDIA_CODEC_INI_C_ */