-static void
-show_setting(gpointer key, gpointer value, gpointer user_data)
-{
- printf("key (%s) -- value (%s)\n", (gchar*)key, (gchar*)value);
-}
-
-void
-dump_settings(GHashTable *settings)
-{
- printf("------------------------------------\n");
- g_hash_table_foreach(settings, show_setting, NULL);
-}
-
-// This is a bit hackish, but effective
-const gchar defaultSettings[] =
-#include "internal_defaults.h"
-;
-
-typedef struct
-{
- gchar *name;
- gchar *description;
- gboolean custom;
- gboolean defalt;
- GKeyFile *keyFile;
-} presets_data_t;
-
-static GKeyFile *standardKeyFile;
-static GKeyFile *customKeyFile;
-static GKeyFile *internalKeyFile;
-static GKeyFile *prefsKeyFile;
-static GList *presetsList;
-
-static gint
-search_group(const gchar *name, gchar **groups)
-{
- gint ii;
-
- //g_debug("search_group\n");
- if (groups == NULL) return -1;
- for (ii = 0; groups[ii] != NULL; ii++)
- {
- //g_debug("%s cmp %s\n", name, groups[ii]);
- if (strcmp(name, groups[ii]) == 0)
- {
- return ii;
- }
- }
- return -1;
-}
-
-presets_data_t *
-presets_list_search(GList *list, const gchar *name)
-{
- GList *link = list;
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- g_debug("search -- %s\n", data->name);
- if (strcmp(name, data->name) == 0)
- {
- return data;
- }
- link = g_list_next(link);
- }
- return NULL;
-}
-
-void
-ghb_set_preset_default(GHashTable *settings)
-{
- const gchar *preset;
- presets_data_t *data;
-
- preset = ghb_settings_get_string (settings, "default_preset");
- data = presets_list_search(presetsList, preset);
- if (data != NULL)
- {
- data->defalt = FALSE;
- }
- preset = ghb_settings_get_string (settings, "preset");
- data = presets_list_search(presetsList, preset);
- if (data != NULL)
- {
- data->defalt = TRUE;
- }
- ghb_settings_set_string(settings, "default_preset", preset);
- ghb_prefs_save(settings);
-}
-
-gint
-ghb_presets_list_index(const gchar *name)
-{
- GList *link = presetsList;
- int ii = 0;
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- if (strcmp(name, data->name) == 0)
- {
- return ii;
- }
- link = g_list_next(link);
- ii++;
- }
- return -1;
-}
-
-gint
-ghb_preset_flags(const gchar *name, gint *index)
-{
- GList *link = presetsList;
- int ii = 0;
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- if (strcmp(name, data->name) == 0)
- {
- gint ret = 0;
-
- *index = ii;
- ret = (data->custom ? PRESET_CUSTOM : 0);
- ret |= (data->defalt ? PRESET_DEFAULT : 0);
- return ret;
- }
- link = g_list_next(link);
- ii++;
- }
- *index = -1;
- return 0;
-}
-
-gchar**
-ghb_presets_get_names()
-{
- gchar **result;
- GList *link = presetsList;
- int ii = 0;
-
- g_debug("ghb_presets_get_names()\n");
- result = g_malloc((g_list_length(presetsList)+1) * sizeof(gchar*));
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- result[ii++] = g_strdup(data->name);
- link = g_list_next(link);
- }
- result[ii] = NULL;
- return result;
-}
-
-gchar**
-ghb_presets_get_descriptions()
-{
- gchar **result;
- GList *link = presetsList;
- int ii = 0;
-
- g_debug("ghb_presets_get_names()\n");
- result = g_malloc((g_list_length(presetsList)+1) * sizeof(gchar*));
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- result[ii++] = g_strdup(data->description);
- link = g_list_next(link);
- }
- result[ii] = NULL;
- return result;
-}
-
-const gchar*
-ghb_presets_get_name(gint index)
-{
- gchar *result = NULL;
- GList *link = presetsList;
- int ii = 0;
-
- g_debug("ghb_presets_get_name()\n");
- while ((link != NULL) && (ii < index))
- {
- link = g_list_next(link);
- ii++;
- }
- if (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- result = data->name;
- }
- return result;
-}
-
-static gboolean
-init_presets_hash_from_key_file(signal_user_data_t *ud, const gchar *name, GKeyFile *keyFile)
-{
- gchar **keys;
- gsize length;
- gchar *str;
-
- // Get key list from internal default presets. This way we do not
- // load any unknown keys.
- keys = g_key_file_get_keys(internalKeyFile, "Presets", &length, NULL);
- if (keys != NULL)
- {
- gint ii;
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- g_debug("key (%s)\n", keys[ii]);
- str = NULL;
- if (name != NULL && keyFile != NULL)
- {
- str = g_key_file_get_string(keyFile, name, keys[ii], NULL);
- g_debug("(%s, %s)\n", keys[ii], str);
- }
- if (str == NULL)
- {
- str = g_key_file_get_string(internalKeyFile, "Presets", keys[ii], NULL);
- }
- if (str != NULL)
- {
- g_debug("name (%s): key (%s) -- str (%s)\n", name, keys[ii], str);
- ghb_settings_set_string(ud->settings, keys[ii], str);
- ghb_ui_update(ud, keys[ii], str);
- g_free(str);
- }
- }
- g_strfreev(keys);
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-preset_to_ui(signal_user_data_t *ud, presets_data_t *data)
-{
- g_debug("preset_to_settings()\n");
- // Initialize the ui from presets file.
- if (data == NULL)
- {
- // Set defaults
- init_presets_hash_from_key_file(ud, NULL, NULL);
- return;
- }
- else
- {
- g_debug("preset name (%s)\n", data->name);
- // Initialize from preset
- init_presets_hash_from_key_file(ud, data->name, data->keyFile);
- }
-}
-
-static void
-preset_update_ui(signal_user_data_t *ud, presets_data_t *data, const gchar *key)
-{
- gchar *str;
-
- g_debug("preset_update_settings()\n");
- // Initialize the ui from presets file.
- if (data == NULL) return;
- str = g_key_file_get_string(data->keyFile, data->name, key, NULL);
- if (str == NULL)
- {
- str = g_key_file_get_string(internalKeyFile, "Presets", key, NULL);
- }
- if (str != NULL)
- {
- ghb_ui_update(ud, key, str);
- g_free(str);
- }
-}
-
-void
-ghb_set_preset(signal_user_data_t *ud, const gchar *name)
-{
- presets_data_t *data;
-
- g_debug("ghb_set_preset() %s\n", name);
- if (name == NULL)
- {
- name = ghb_presets_get_name(0);
- }
- if (name == NULL)
- {
- preset_to_ui(ud, NULL);
- }
- else
- {
- data = presets_list_search(presetsList, name);
- preset_to_ui(ud, data);
- ghb_settings_set_string(ud->settings, "preset", name);
- }
- ghb_pref_audio_init(ud);
-}
-
-void
-ghb_update_from_preset(
- signal_user_data_t *ud,
- const gchar *name,
- const gchar *key)
-{
- presets_data_t *data;
-
- g_debug("ghb_update_from_preset() %s %s\n", name, key);
- if (name == NULL) return;
- data = presets_list_search(presetsList, name);
- preset_update_ui(ud, data, key);
-}
-
-static void
-build_presets_list(GHashTable *settings)
-{
- GList *link = presetsList;
- presets_data_t *data;
- gchar **custom, **standard;
- gsize clength, slength;
- gint ii, jj;
-
- g_debug("build_presets_list ()\n");
- // First clear out the old presets list
- while (link != NULL)
- {
- data = (presets_data_t*)link->data;
- g_free(data->name);
- if (data->description != NULL)
- g_free(data->description);
- g_free(data);
- link = g_list_delete_link (link, link);
- }
- presetsList = NULL;
-
- // Now build up the new list
- const gchar *def_name = ghb_settings_get_string(settings, "default_preset");
- custom = g_key_file_get_groups(customKeyFile, &clength);
- standard = g_key_file_get_groups(standardKeyFile, &slength);
- if ((slength + clength) <= 0) return;
- jj = 0;
- for (ii = 0; ii < slength; ii++)
- {
- if (search_group(standard[ii], custom) < 0)
- {
- gchar *desc;
- data = g_malloc(sizeof(presets_data_t));
- data->name = g_strdup(standard[ii]);
- data->keyFile = standardKeyFile;
- data->custom = FALSE;
- data->defalt = FALSE;
- if ((def_name != NULL) && (strcmp(def_name, data->name) == 0))
- {
- data->defalt = TRUE;
- }
- desc = g_key_file_get_string(standardKeyFile, standard[ii], "preset_description", NULL);
- data->description = desc;
- presetsList = g_list_append(presetsList, data);
- }
- }
- for (ii = 0; ii < clength; ii++)
- {
- gchar *desc;
- data = g_malloc(sizeof(presets_data_t));
- data->name = g_strdup(custom[ii]);
- data->keyFile = customKeyFile;
- data->custom = TRUE;
- data->defalt = FALSE;
- if ((def_name != NULL) && (strcmp(def_name, data->name) == 0))
- {
- data->defalt = TRUE;
- }
- desc = g_key_file_get_string(customKeyFile, custom[ii], "preset_description", NULL);
- data->description = desc;
- presetsList = g_list_append(presetsList, data);
- }
- g_strfreev(custom);
- g_strfreev(standard);
-}
-
-static void
-store_key_file(GKeyFile *key_file, const gchar *name)
-{
- gchar *settingsString;
- const gchar *dir;
- gsize length;
- gchar *config;
- gint fd;
-
- g_debug("store_key_file ()\n");
- settingsString = g_key_file_to_data(key_file, &length, NULL);
-
- dir = g_get_user_config_dir();
- config = g_strdup_printf ("%s/ghb", dir);
- if (!g_file_test(config, G_FILE_TEST_IS_DIR))
- {
- g_mkdir (config, 0755);
- }
- g_free(config);
- config = g_strdup_printf ("%s/ghb/%s", dir, name);
- fd = g_open(config, O_RDWR|O_CREAT|O_TRUNC, 0777);
- write(fd, settingsString, length);
- close(fd);
- g_debug("prefs:\n%s\n", settingsString);
- g_free(settingsString);
-}
-
-void
-ghb_prefs_to_ui(signal_user_data_t *ud)
-{
- const gchar *str;
-
- str = ghb_settings_get_string(ud->settings, "default_source");
- ghb_settings_set_string (ud->settings, "source", str);
- str = ghb_settings_get_string(ud->settings, "destination_dir");
-
- gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
- ghb_ui_update(ud, "destination", path);
- g_free(path);
-}
-
-static gboolean prefs_initializing = FALSE;
-
-void
-ghb_prefs_save(GHashTable *settings)
-{
- gint ii;
- const gchar *value;
- gchar **keys;
- gsize length;
-
- if (prefs_initializing) return;
- keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
- if (keys != NULL)
- {
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- value = ghb_settings_get_string(settings, keys[ii]);
- if (value != NULL)
- {
- g_key_file_set_value(prefsKeyFile, "Preferences", keys[ii], value);
- }
- }
- g_strfreev(keys);
- store_key_file(prefsKeyFile, "preferences");
- }
-}
-
-void
-ghb_pref_save(GHashTable *settings, const gchar *key)
-{
- const gchar *value;
-
- if (prefs_initializing) return;
- value = ghb_settings_get_string(settings, key);
- if (value != NULL)
- {
- g_key_file_set_value(prefsKeyFile, "Preferences", key, value);
- store_key_file(prefsKeyFile, "preferences");
- }
-}
-
-#if 0
-static void
-dump_key_file(GKeyFile *keyFile, const gchar *section)
-{
- gint ii;
- gchar **keys;
- gsize length;
-
- // Get defaults from internal defaults
- keys = g_key_file_get_keys(keyFile, section, &length, NULL);
- if (keys != NULL)
- {
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- gchar *str;
-
- str = g_key_file_get_string(keyFile, section, keys[ii], NULL);
- if (str != NULL)
- {
- g_message("Preference: key (%s) -- str (%s)\n", keys[ii], str);
- g_free(str);
- }
- else
- {
- g_message("Preference: key (%s) -- str **none**\n", keys[ii]);
- }
- }
- g_strfreev(keys);
- }
- else
- {
- g_message("no keys");
- }
-}
-#endif
-
-void
-ghb_prefs_load(signal_user_data_t *ud)
-{
- gint ii;
- const gchar *dir;
- gchar *config;
- gchar *value;
- gchar **keys;
- gsize length;
- gboolean res;
-
- prefs_initializing = TRUE;
- internalKeyFile = g_key_file_new();
- res = g_key_file_load_from_data( internalKeyFile, defaultSettings,
- sizeof(defaultSettings), G_KEY_FILE_NONE, NULL);
- if (!res)
- g_warning("Failed to initialize internal defaults\n");
-
- keys = g_key_file_get_keys(internalKeyFile, "Initialization", &length, NULL);
- if (keys != NULL)
- {
- gint ii;
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- gchar *str;
-
- g_debug("key (%s)\n", keys[ii]);
- str = g_key_file_get_string(internalKeyFile, "Initialization", keys[ii], NULL);
- if (str != NULL)
- {
- g_debug("Initialization: key (%s) -- str (%s)\n", keys[ii], str);
- ghb_settings_set_string(ud->settings, keys[ii], str);
- ghb_ui_update(ud, keys[ii], str);
- g_free(str);
- }
- }
- g_strfreev(keys);
- }
- prefsKeyFile = g_key_file_new();
- dir = g_get_user_config_dir();
- config = g_strdup_printf ("%s/ghb/preferences", dir);
- if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
- {
- g_key_file_load_from_file( prefsKeyFile, config, G_KEY_FILE_KEEP_COMMENTS, NULL);
- }
- value = g_key_file_get_value(prefsKeyFile, "Preferences", "version", NULL);
- if (value == NULL)
- {
- gint ii;
-
- // Get defaults from internal defaults
- keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
- if (keys != NULL)
- {
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- gchar *str;
-
- str = g_key_file_get_string(internalKeyFile, "Preferences", keys[ii], NULL);
- if (str != NULL)
- {
- g_debug("Preference: key (%s) -- str (%s)\n", keys[ii], str);
- g_key_file_set_value(prefsKeyFile, "Preferences", keys[ii], str);
- g_free(str);
- }
- }
- g_strfreev(keys);
- }
- const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
- g_key_file_set_value(prefsKeyFile, "Preferences", "destination_dir", dir);
- store_key_file(prefsKeyFile, "preferences");
- }
- g_free(config);
- keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
- if (keys != NULL)
- {
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- value = g_key_file_get_value(prefsKeyFile, "Preferences", keys[ii], NULL);
- if (value != NULL)
- {
- ghb_settings_set_string(ud->settings, keys[ii], value);
- ghb_ui_update(ud, keys[ii], value);
- g_free(value);
- }
- else
- {
- value = g_key_file_get_value(internalKeyFile, "Preferences", keys[ii], NULL);
- if (value != NULL)
- {
- ghb_settings_set_string(ud->settings, keys[ii], value);
- ghb_ui_update(ud, keys[ii], value);
- g_free(value);
- }
- }
- }
- g_strfreev(keys);
- }
- gint bval = ghb_settings_get_int(ud->settings, "show_presets");
- ghb_ui_update_int(ud, "show_presets", bval);
- if (ghb_settings_get_bool(ud->settings, "hbfd_feature"))
- {
- GtkAction *action;
- bval = ghb_settings_get_int(ud->settings, "hbfd");
- ghb_ui_update_int(ud, "hbfd", bval);
- action = GHB_ACTION (ud->builder, "hbfd");
- gtk_action_set_visible(action, TRUE);
- }
- else
- {
- ghb_ui_update_int(ud, "hbfd", 0);
- }
- prefs_initializing = FALSE;
-}
-
-void
-ghb_presets_load(signal_user_data_t *ud)
-{
- const gchar *dir;
- gchar *config;
- GHashTable *settings = ud->settings;
-
- g_debug("ghb_presets_load()\n");
- customKeyFile = g_key_file_new();
- standardKeyFile = g_key_file_new();
- dir = g_get_user_config_dir();
- config = g_strdup_printf ("%s/ghb/custom_presets", dir);
- if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
- {
- g_key_file_load_from_file( customKeyFile, config,
- G_KEY_FILE_KEEP_COMMENTS, NULL);
- }
- g_free(config);
- // Try current dir first. Makes testing prior to installation easier
- if (g_file_test("./standard_presets", G_FILE_TEST_IS_REGULAR))
- {
- g_key_file_load_from_file( standardKeyFile, "./standard_presets",
- G_KEY_FILE_KEEP_COMMENTS, NULL);
- }
- else
- {
- // Try users config dir
- config = g_strdup_printf ("%s/ghb/standard_presets", dir);
- if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
- {
- g_key_file_load_from_file( standardKeyFile, config,
- G_KEY_FILE_KEEP_COMMENTS, NULL);
- g_free(config);
- }
- else
- {
- const gchar* const *dirs;
- gint ii;
- g_free(config);
- dirs = g_get_system_data_dirs();
- if (dirs != NULL)
- {
- for (ii = 0; dirs[ii] != NULL; ii++)
- {
- config = g_strdup_printf("%s/ghb/standard_presets", dirs[ii]);
- if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
- {
- g_key_file_load_from_file( standardKeyFile, config,
- G_KEY_FILE_KEEP_COMMENTS, NULL);
- break;
- }
- g_free(config);
- }
- }
- }
- }
- build_presets_list(settings);
-}
-
-static void
-presets_store()
-{
- g_debug("presets_store ()\n");
- store_key_file(customKeyFile, "custom_presets");
-}
-
-typedef struct
-{
- const gchar *name;
- GKeyFile *keyFile;
- gboolean autoscale;
-} store_key_info_t;
-
-static void
-store_to_key_file(gpointer xkey, gpointer xvalue, gpointer xski)
-{
- store_key_info_t *ski = (store_key_info_t*)xski;
- setting_value_t *value = (setting_value_t *)xvalue;
- gchar *key = (gchar*)xkey;
- gchar *str;
-
- if (!ski->autoscale)
- {
- if (strcmp(key, "scale_width"))
- {
- key = "max_width";
- }
- if (strcmp(key, "scale_height"))
- {
- key = "max_height";
- }
- }
- str = g_key_file_get_string(internalKeyFile, "Presets", key, NULL);
- if (str == NULL)
- {
- g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
- return;
- }
- g_debug("comparing: key (%s) -- (%s) == (%s)\n", (gchar*)key, str, value->svalue);
- if (strcmp(str, value->shortOpt) != 0)
- {
- // Differs from default value. Store it.
- g_debug("storing: key (%s) -- (%s)\n", (gchar*)key, value->shortOpt);
- gchar *tmp = g_strescape (value->shortOpt, NULL);
- g_key_file_set_value(ski->keyFile, ski->name, (gchar*)key, tmp);
- g_free(tmp);
- }
- else
- {
- // Remove it if it exists already in keyfile
- g_key_file_remove_key (ski->keyFile, ski->name, (gchar*)key, NULL);
- }
- g_free(str);
-}
-
-void
-ghb_settings_save(signal_user_data_t *ud, const gchar *name)
-{
- store_key_info_t ski;
-
- g_debug("ghb_settings_save ()\n");
- ski.name = name;
- ski.keyFile = customKeyFile;
- ski.autoscale = ghb_settings_get_bool (ud->settings, "autoscale");
- g_hash_table_foreach(ud->settings, store_to_key_file, &ski);
- presets_store();
- build_presets_list(ud->settings);
- ud->dont_clear_presets = TRUE;
- ghb_set_preset (ud, name);
- ud->dont_clear_presets = FALSE;
-}
-
-// Checks to see if the preset is in standard presets
-// I allow standard to be overridden by adding a preset with the
-// same name to the custom list. So to determine if the named
-// preset is standard, I must first check to see if is in the
-// custom list.
-gboolean
-ghb_presets_is_standard(const gchar *name)
-{
- g_debug("ghb_presets_is_standard()\n");
- if (g_key_file_has_group(customKeyFile, name))
- {
- // The preset is in the custom list, so it
- // can not be a standard.
- return FALSE;
- }
- return g_key_file_has_group(standardKeyFile, name);
-}
-
-// This function will not remove presets from the standard preset list.
-// Return false if attempt is made.
-gboolean
-ghb_presets_remove(GHashTable *settings, const gchar *name)
-{
- g_debug("ghb_presets_remove()\n");
- if (g_key_file_has_group(customKeyFile, name))
- {
- g_debug("\t removing %s\n", name);
- g_key_file_remove_group(customKeyFile, name, NULL);
- presets_store();
- build_presets_list(settings);
- return TRUE;
- }
- return FALSE;
-}
-
-enum
-{
- X264_OPT_DEBLOCK,
- X264_OPT_INT,
- X264_OPT_COMBO,
- X264_OPT_BOOL,
-};
-
-struct x264_opt_map_s
-{
- gchar **opt_syns;
- gchar *name;
- gchar *def_val;
- gint type;
- gboolean found;
-};
-
-static gchar *x264_ref_syns[] = {"ref", "frameref", NULL};
-static gchar *x264_mixed_syns[] = {"mixed-refs", NULL};
-static gchar *x264_bframes_syns[] = {"bframes", NULL};
-static gchar *x264_direct_syns[] = {"direct", "direct-pred", NULL};
-static gchar *x264_weightb_syns[] = {"weightb", "weight-b", NULL};
-static gchar *x264_brdo_syns[] = {"brdo", "b-rdo", NULL};
-static gchar *x264_bime_syns[] = {"bime", NULL};
-static gchar *x264_bpyramid_syns[] = {"b-pyramid", NULL};
-static gchar *x264_me_syns[] = {"me", NULL};
-static gchar *x264_merange_syns[] = {"merange", "me-range", NULL};
-static gchar *x264_subme_syns[] = {"subme", "subq", NULL};
-static gchar *x264_analyse_syns[] = {"analyse", "partitions", NULL};
-static gchar *x264_8x8dct_syns[] = {"8x8dct", NULL};
-static gchar *x264_deblock_syns[] = {"deblock", "filter", NULL};
-static gchar *x264_trellis_syns[] = {"trellis", NULL};
-static gchar *x264_pskip_syns[] = {"no-fast-pskip", NULL};
-static gchar *x264_decimate_syns[] = {"no-dct-decimate", NULL};
-static gchar *x264_cabac_syns[] = {"cabac", NULL};
-
-static gint
-find_syn_match(const gchar *opt, gchar **syns)
-{
- gint ii;
- for (ii = 0; syns[ii] != NULL; ii++)
- {
- if (strcmp(opt, syns[ii]) == 0)
- return ii;
- }
- return -1;
-}
-
-struct x264_opt_map_s x264_opt_map[] =
-{
- {x264_ref_syns, "x264_refs", "1", X264_OPT_INT},
- {x264_mixed_syns, "x264_mixed_refs", "0", X264_OPT_BOOL},
- {x264_bframes_syns, "x264_bframes", "0", X264_OPT_INT},
- {x264_direct_syns, "x264_direct", "spatial", X264_OPT_COMBO},
- {x264_weightb_syns, "x264_weighted_bframes", "0", X264_OPT_BOOL},
- {x264_brdo_syns, "x264_brdo", "0", X264_OPT_BOOL},
- {x264_bime_syns, "x264_bime", "0", X264_OPT_BOOL},
- {x264_bpyramid_syns, "x264_bpyramid", "0", X264_OPT_BOOL},
- {x264_me_syns, "x264_me", "hex", X264_OPT_COMBO},
- {x264_merange_syns, "x264_merange", "16", X264_OPT_INT},
- {x264_subme_syns, "x264_subme", "5", X264_OPT_COMBO},
- {x264_analyse_syns, "x264_analyse", "some", X264_OPT_COMBO},
- {x264_8x8dct_syns, "x264_8x8dct", "0", X264_OPT_BOOL},
- {x264_deblock_syns, "x264_deblock_alpha", "0,0", X264_OPT_DEBLOCK},
- {x264_deblock_syns, "x264_deblock_beta", "0,0", X264_OPT_DEBLOCK},
- {x264_trellis_syns, "x264_trellis", "0", X264_OPT_COMBO},
- {x264_pskip_syns, "x264_no_fast_pskip", "0", X264_OPT_BOOL},
- {x264_decimate_syns, "x264_no_dct_decimate", "0", X264_OPT_BOOL},
- {x264_cabac_syns, "x264_cabac", "1", X264_OPT_BOOL},
-};
-#define X264_OPT_MAP_SIZE (sizeof(x264_opt_map)/sizeof(struct x264_opt_map_s))
-
-static const gchar*
-x264_opt_get_default(const gchar *opt)
-{
- gint jj;
- for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
- {
- if (find_syn_match(opt, x264_opt_map[jj].opt_syns) >= 0)
- {
- return x264_opt_map[jj].def_val;
- }
- }
- return "";
-}
-
-static void
-x264_update_int(signal_user_data_t *ud, const gchar *name, const gchar *val)
-{
- gdouble dvalue;
- gchar *end;
-
- if (val == NULL) return;
- dvalue = g_strtod (val, &end);
- ghb_ui_update_int(ud, name, dvalue);
-}
-
-static void
-x264_update_bool(signal_user_data_t *ud, const gchar *name, const gchar *val)
-{
- if (val == NULL)
- ghb_ui_update(ud, name, "1");
- else
- ghb_ui_update(ud, name, val);
-}
-
-static void
-x264_update_combo(signal_user_data_t *ud, const gchar *name, const gchar *val)
-{
- GtkTreeModel *store;
- GtkTreeIter iter;
- gchar *shortOpt;
- gint ivalue;
- gboolean foundit = FALSE;
- GtkWidget *widget;
-
- if (val == NULL) return;
- widget = GHB_WIDGET(ud->builder, name);
- if (widget == NULL)
- {
- g_debug("Failed to find widget for key: %s\n", name);
- return;
- }
- store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
- if (gtk_tree_model_get_iter_first (store, &iter))
- {
- do
- {
- gtk_tree_model_get(store, &iter, 2, &shortOpt, 3, &ivalue, -1);
- if (strcmp(shortOpt, val) == 0)
- {
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
- g_free(shortOpt);
- foundit = TRUE;
- break;
- }
- g_free(shortOpt);
- } while (gtk_tree_model_iter_next (store, &iter));
- }
- if (!foundit)
- {
- if (gtk_tree_model_get_iter_first (store, &iter))
- {
- do
- {
- gtk_tree_model_get(store, &iter, 2, &shortOpt, 3, &ivalue, -1);
- if (strcmp(shortOpt, "custom") == 0)
- {
- gtk_list_store_set(GTK_LIST_STORE(store), &iter, 4, val, -1);
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
- g_free(shortOpt);
- foundit = TRUE;
- break;
- }
- g_free(shortOpt);
- } while (gtk_tree_model_iter_next (store, &iter));
- }
- }
- // Its possible the value hasn't changed. Since settings are only
- // updated when the value changes, I'm initializing settings here as well.
- ghb_widget_to_setting(ud->settings, widget);
-}
-
-static void
-x264_update_deblock(signal_user_data_t *ud, const gchar *xval)
-{
- gdouble avalue, bvalue;
- gchar *end;
- gchar *val;
- gchar *bval = NULL;
-
- if (xval == NULL) return;
- val = g_strdup(xval);
- bvalue = avalue = 0;
- if (val != NULL)
- {
- gchar *pos = strchr(val, ',');
- if (pos != NULL)
- {
- bval = pos + 1;
- *pos = 0;
- }
- avalue = g_strtod (val, &end);
- if (bval != NULL)
- {
- bvalue = g_strtod (bval, &end);
- }
- }
- g_free(val);
- ghb_ui_update_int(ud, "x264_deblock_alpha", avalue);
- ghb_ui_update_int(ud, "x264_deblock_beta", bvalue);
-}
-
-void
-ghb_x264_parse_options(signal_user_data_t *ud, const gchar *options)
-{
- gchar **split = g_strsplit(options, ":", -1);
- if (split == NULL) return;
-
- gint ii;
- gint jj;
-
- for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
- x264_opt_map[jj].found = FALSE;
-
- for (ii = 0; split[ii] != NULL; ii++)
- {
- gchar *val = NULL;
- gchar *pos = strchr(split[ii], '=');
- if (pos != NULL)
- {
- val = pos + 1;
- *pos = 0;
- }
- for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
- {
- if (find_syn_match(split[ii], x264_opt_map[jj].opt_syns) >= 0)
- {
- x264_opt_map[jj].found = TRUE;
- switch(x264_opt_map[jj].type)
- {
- case X264_OPT_INT:
- x264_update_int(ud, x264_opt_map[jj].name, val);
- break;
- case X264_OPT_BOOL:
- x264_update_bool(ud, x264_opt_map[jj].name, val);
- break;
- case X264_OPT_COMBO:
- x264_update_combo(ud, x264_opt_map[jj].name, val);
- break;
- case X264_OPT_DEBLOCK:
- // dirty little hack. mark deblock_beta found as well
- x264_opt_map[jj+1].found = TRUE;
- x264_update_deblock(ud, val);
- break;
- }
- break;
- }
- }
- }
- // For any options not found in the option string, set ui to
- // default values
- for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
- {
- if (!x264_opt_map[jj].found)
- {
- gchar *val = strdup(x264_opt_map[jj].def_val);
- switch(x264_opt_map[jj].type)
- {
- case X264_OPT_INT:
- x264_update_int(ud, x264_opt_map[jj].name, val);
- break;
- case X264_OPT_BOOL:
- x264_update_bool(ud, x264_opt_map[jj].name, val);
- break;
- case X264_OPT_COMBO:
- x264_update_combo(ud, x264_opt_map[jj].name, val);
- break;
- case X264_OPT_DEBLOCK:
- x264_update_deblock(ud, val);
- break;
- }
- x264_opt_map[jj].found = TRUE;
- g_free(val);
- }
- }
- g_strfreev(split);
-}
-
-gchar*
-get_deblock_val(signal_user_data_t *ud)
-{
- const gchar *alpha, *beta;
- gchar *result;
- alpha = ghb_settings_get_string(ud->settings, "x264_deblock_alpha");
- beta = ghb_settings_get_string(ud->settings, "x264_deblock_beta");
- result = g_strdup_printf("%s,%s", alpha, beta);
- return result;
-}
-
-void
-ghb_x264_opt_update(signal_user_data_t *ud, GtkWidget *widget)
-{
- gint jj;
- const gchar *name = gtk_widget_get_name(widget);
- gchar **opt_syns = NULL;
- const gchar *def_val = NULL;
- gint type;
-
- for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
- {
- if (strcmp(name, x264_opt_map[jj].name) == 0)
- {
- // found the options that needs updating
- opt_syns = x264_opt_map[jj].opt_syns;
- def_val = x264_opt_map[jj].def_val;
- type = x264_opt_map[jj].type;
- break;
- }
- }
- if (opt_syns != NULL)
- {
- GString *x264opts = g_string_new("");
- const gchar *options;
- options = ghb_settings_get_string(ud->settings, "x264_options");
- gchar **split = g_strsplit(options, ":", -1);
- gint ii;
- gboolean foundit = FALSE;
-
- if (split == NULL) return;
- for (ii = 0; split[ii] != NULL; ii++)
- {
- gint syn;
- gchar *val = NULL;
- gchar *pos = strchr(split[ii], '=');
- if (pos != NULL)
- {
- val = pos + 1;
- *pos = 0;
- }
- syn = find_syn_match(split[ii], opt_syns);
- if (syn >= 0)
- { // Updating this option
- gchar *val;
- foundit = TRUE;
- if (type == X264_OPT_DEBLOCK)
- val = get_deblock_val(ud);
- else
- val = ghb_widget_string(widget);
- if (strcmp(def_val, val) != 0)
- {
- g_string_append_printf(x264opts, "%s=%s:", opt_syns[syn], val);
- }
- g_free(val);
- }
- else if (val != NULL)
- g_string_append_printf(x264opts, "%s=%s:", split[ii], val);
- else
- g_string_append_printf(x264opts, "%s:", split[ii]);
-
- }
- if (!foundit)
- {
- gchar *val;
- if (type == X264_OPT_DEBLOCK)
- val = get_deblock_val(ud);
- else
- val = ghb_widget_string(widget);
- if (strcmp(def_val, val) != 0)
- {
- g_string_append_printf(x264opts, "%s=%s:", opt_syns[0], val);
- }
- g_free(val);
- }
- // Update the options value
- // strip the trailing ":"
- gchar *result;
- gint len;
- result = g_string_free(x264opts, FALSE);
- len = strlen(result);
- if (len > 0) result[len - 1] = 0;
- ghb_ui_update(ud, "x264_options", result);
- }
-}
-
-static void
-x264_remove_opt(gchar **opts, gchar **opt_syns)
-{
- gint ii;
- for (ii = 0; opts[ii] != NULL; ii++)
- {
- gchar *opt;
- opt = g_strdup(opts[ii]);
- gchar *pos = strchr(opt, '=');
- if (pos != NULL)
- {
- *pos = 0;
- }
- if (find_syn_match(opt, opt_syns) >= 0)
- {
- // Mark as deleted
- opts[ii][0] = 0;
- }
- g_free(opt);
- }
-}
-
-// Construct the x264 options string
-// The result is allocated, so someone must free it at some point.
-gchar*
-ghb_sanitize_x264opts(signal_user_data_t *ud, const gchar *options)
-{
- GString *x264opts = g_string_new("");
- gchar **split = g_strsplit(options, ":", -1);
-
- // Remove entries that match the defaults
- gint ii;
- for (ii = 0; split[ii] != NULL; ii++)
- {
- gchar *val = NULL;
- gchar *opt = g_strdup(split[ii]);
- gchar *pos = strchr(opt, '=');
- if (pos != NULL)
- {
- val = pos + 1;
- *pos = 0;
- }
- else
- {
- val = "1";
- }
- const gchar *def_val = x264_opt_get_default(opt);
- if (strcmp(val, def_val) == 0)
- {
- // Matches the default, so remove it
- split[ii][0] = 0;
- }
- g_free(opt);
- }
- gint refs = ghb_settings_get_int(ud->settings, "x264_refs");
- if (refs <= 1)
- {
- x264_remove_opt(split, x264_mixed_syns);
- }
- gint subme = ghb_settings_get_int(ud->settings, "x264_subme");
- if (subme < 6)
- {
- x264_remove_opt(split, x264_brdo_syns);
- }
- gint bframes = ghb_settings_get_int(ud->settings, "x264_bframes");
- if (bframes == 0)
- {
- x264_remove_opt(split, x264_weightb_syns);
- x264_remove_opt(split, x264_brdo_syns);
- x264_remove_opt(split, x264_bime_syns);
- }
- if (bframes <= 1)
- {
- x264_remove_opt(split, x264_bpyramid_syns);
- }
- const gchar *me = ghb_settings_get_string(ud->settings, "x264_me");
- if (!(strcmp(me, "umh") == 0 || strcmp(me, "esa") == 0))
- {
- x264_remove_opt(split, x264_merange_syns);
- }
- if (!ghb_settings_get_bool(ud->settings, "x264_cabac"))
- {
- x264_remove_opt(split, x264_trellis_syns);
- }
- gint analyse = ghb_settings_get_int(ud->settings, "x264_analyse");
- if (analyse == 1)
- {
- x264_remove_opt(split, x264_direct_syns);
- }
- for (ii = 0; split[ii] != NULL; ii++)
- {
- if (split[ii][0] != 0)
- g_string_append_printf(x264opts, "%s:", split[ii]);
- }
- // strip the trailing ":"
- gchar *result;
- gint len;
- result = g_string_free(x264opts, FALSE);
- len = strlen(result);
- if (len > 0) result[len - 1] = 0;
- return result;
-}
-
-static gint pref_acodec[8];
-static gint pref_bitrate[8];
-static gint pref_rate[8];
-static gint pref_mix[8];
-static gdouble pref_drc[8];
-static gint pref_audio_count = 0;
-
-void
-ghb_pref_audio_init(signal_user_data_t *ud)
-{
- const gchar *acodec, *bitrate, *rate, *mix, *drc;
- gchar **split_acodec, **split_bitrate, **split_rate;
- gchar **split_mix, **split_drc;
-
- acodec = ghb_settings_get_string(ud->settings, "pref_audio_codec");
- bitrate = ghb_settings_get_string(ud->settings, "pref_audio_bitrate");
- rate = ghb_settings_get_string(ud->settings, "pref_audio_rate");
- mix = ghb_settings_get_string(ud->settings, "pref_audio_mix");
- drc = ghb_settings_get_string(ud->settings, "pref_audio_drc");
- split_acodec = g_strsplit(acodec, ",", 8);
- split_bitrate = g_strsplit(bitrate, ",", 8);
- split_rate = g_strsplit(rate, ",", 8);
- split_mix = g_strsplit(mix, ",", 8);
- split_drc = g_strsplit(drc, ",", 8);
- if (split_acodec == NULL)
- { // This should never happen, but just in case...
- split_acodec = g_strsplit("faac", ",", -1);
- }
- gint ii;
- for (ii = 0; split_acodec[ii]; ii++)
- {
- pref_acodec[ii] = ghb_lookup_acodec(split_acodec[ii]);
- }
- pref_audio_count = ii;
- for (ii = 0; split_bitrate && split_bitrate[ii]; ii++)
- {
- pref_bitrate[ii] = ghb_lookup_bitrate(split_bitrate[ii]);
- }
- for (ii = 0; ii < pref_audio_count; ii++)
- {
- pref_bitrate[ii] = pref_bitrate[0];
- }
- for (ii = 0; split_rate && split_rate[ii]; ii++)
- {
- pref_rate[ii] = ghb_lookup_rate(split_rate[ii]);
- }
- for (ii = 0; ii < pref_audio_count; ii++)
- {
- pref_rate[ii] = pref_rate[0];
- }
- for (ii = 0; split_mix && split_mix[ii]; ii++)
- {
- pref_mix[ii] = ghb_lookup_mix(split_mix[ii]);
- }
- for (ii = 0; ii < pref_audio_count; ii++)
- {
- pref_mix[ii] = pref_mix[0];
- }
- for (ii = 0; split_drc && split_drc[ii]; ii++)
- {
- pref_drc[ii] = ghb_lookup_drc(split_drc[ii]);
- }
- for (ii = 0; ii < pref_audio_count; ii++)
- {
- pref_drc[ii] = pref_drc[0];
- }
-}
-
-gint
-ghb_pref_acount()
-{
- return pref_audio_count;
-}
-
-gint
-ghb_pref_acodec(gint index)
-{
- if (index >= pref_audio_count)
- return 0;
- return pref_acodec[index];
-}
-
-gint
-ghb_pref_bitrate(gint index)
-{
- if (index >= pref_audio_count)
- return 0;
- return pref_bitrate[index];
-}
-
-gint
-ghb_pref_rate(gint index)
-{
- if (index >= pref_audio_count)
- return 0;
- return pref_rate[index];
-}
-
-gint
-ghb_pref_mix(gint index)
-{
- if (index >= pref_audio_count)
- return 0;
- return pref_mix[index];
-}
-
-gdouble
-ghb_pref_drc(gint index)
-{
- if (index >= pref_audio_count)
- return 0;
- return pref_drc[index];
-}
-