1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
6 * settings.c is free software.
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
17 #include <glib/gstdio.h>
21 #include "hb-backend.h"
24 void dump_settings(GValue *settings);
25 void ghb_pref_audio_init(signal_user_data_t *ud);
28 debug_get_object(GtkBuilder* b, const gchar *n)
30 g_message("name %s\n", n);
31 return gtk_builder_get_object(b, n);
37 return ghb_dict_value_new();
41 ghb_settings_set_value(
46 if (key == NULL || value == NULL)
48 ghb_dict_insert(settings, g_strdup(key), ghb_value_dup(value));
52 ghb_settings_take_value(GValue *settings, const gchar *key, GValue *value)
54 ghb_dict_insert(settings, g_strdup(key), value);
58 ghb_settings_set_string(
64 value = ghb_string_value_new(sval);
65 ghb_dict_insert(settings, g_strdup(key), value);
69 ghb_settings_set_double(GValue *settings, const gchar *key, gdouble dval)
72 value = ghb_double_value_new(dval);
73 ghb_dict_insert(settings, g_strdup(key), value);
77 ghb_settings_set_int64(GValue *settings, const gchar *key, gint64 ival)
80 value = ghb_int64_value_new(ival);
81 ghb_dict_insert(settings, g_strdup(key), value);
85 ghb_settings_set_int(GValue *settings, const gchar *key, gint ival)
88 value = ghb_int64_value_new((gint64)ival);
89 ghb_dict_insert(settings, g_strdup(key), value);
93 ghb_settings_set_boolean(GValue *settings, const gchar *key, gboolean bval)
96 value = ghb_boolean_value_new(bval);
97 ghb_dict_insert(settings, g_strdup(key), value);
101 ghb_settings_set_combo(
106 const gchar *shortOpt,
111 value = ghb_combo_value_new(index, option, shortOpt, svalue, ivalue);
112 ghb_dict_insert(settings, g_strdup(key), value);
116 ghb_settings_get_value(GValue *settings, const gchar *key)
119 value = ghb_dict_lookup(settings, key);
121 g_warning("returning null (%s)", key);
126 ghb_settings_get_boolean(GValue *settings, const gchar *key)
129 value = ghb_settings_get_value(settings, key);
130 if (value == NULL) return FALSE;
131 return ghb_value_boolean(value);
135 ghb_settings_get_int64(GValue *settings, const gchar *key)
138 value = ghb_settings_get_value(settings, key);
139 if (value == NULL) return 0;
140 return ghb_value_int64(value);
144 ghb_settings_get_int(GValue *settings, const gchar *key)
147 value = ghb_settings_get_value(settings, key);
148 if (value == NULL) return 0;
149 return ghb_value_int(value);
153 ghb_settings_get_double(GValue *settings, const gchar *key)
156 value = ghb_settings_get_value(settings, key);
157 if (value == NULL) return 0;
158 return ghb_value_double(value);
162 ghb_settings_get_string(GValue *settings, const gchar *key)
165 value = ghb_settings_get_value(settings, key);
166 if (value == NULL) return g_strdup("");
167 return ghb_value_string(value);
171 ghb_settings_get_combo_index(GValue *settings, const gchar *key)
174 value = ghb_settings_get_value(settings, key);
175 if (value == NULL) return 0;
177 if (G_VALUE_TYPE(value) != ghb_combodata_get_type())
179 cd = g_value_get_boxed(value);
184 ghb_settings_get_combo_option(GValue *settings, const gchar *key)
187 value = ghb_settings_get_value(settings, key);
188 if (value == NULL) return g_strdup("");
190 if (G_VALUE_TYPE(value) != ghb_combodata_get_type())
192 cd = g_value_get_boxed(value);
193 return g_strdup(cd->option);
196 // Map widget names to setting keys
197 // Widgets that map to settings have names
198 // of this format: s_<setting key>
200 get_setting_key(GtkWidget *widget)
204 g_debug("get_setting_key ()\n");
205 if (widget == NULL) return NULL;
206 if (GTK_IS_ACTION(widget))
207 name = gtk_action_get_name(GTK_ACTION(widget));
209 name = gtk_widget_get_name(widget);
213 // Bad widget pointer? Should never happen.
214 g_debug("Bad widget\n");
221 ghb_widget_value(GtkWidget *widget)
223 GValue *value = NULL;
229 g_debug("NULL widget\n");
233 type = GTK_WIDGET_TYPE(widget);
234 if (GTK_IS_ACTION(widget))
235 name = gtk_action_get_name(GTK_ACTION(widget));
237 name = gtk_widget_get_name(widget);
238 g_debug("ghb_widget_value widget (%s)\n", name);
239 if (type == GTK_TYPE_ENTRY)
241 const gchar *str = gtk_entry_get_text(GTK_ENTRY(widget));
242 value = ghb_string_value_new(str);
244 else if (type == GTK_TYPE_RADIO_BUTTON)
246 g_debug("\tradio_button");
248 bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
249 value = ghb_boolean_value_new(bval);
251 else if (type == GTK_TYPE_CHECK_BUTTON)
253 g_debug("\tcheck_button");
255 bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
256 value = ghb_boolean_value_new(bval);
258 else if (type == GTK_TYPE_TOGGLE_ACTION)
260 g_debug("\ttoggle action");
262 bval = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget));
263 value = ghb_boolean_value_new(bval);
265 else if (type == GTK_TYPE_CHECK_MENU_ITEM)
267 g_debug("\tcheck_menu_item");
269 bval = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
270 value = ghb_boolean_value_new(bval);
272 else if (type == GTK_TYPE_COMBO_BOX)
274 g_debug("\tcombo_box");
277 gchar *shortOpt, *option, *svalue;
280 index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
281 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
282 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
284 gtk_tree_model_get(store, &iter, 0, &option, 2, &shortOpt,
285 3, &ivalue, 4, &svalue, -1);
286 value = ghb_combo_value_new(index, option, shortOpt,
294 value = ghb_combo_value_new(-1, "", "", "", 0);
298 else if (type == GTK_TYPE_COMBO_BOX_ENTRY)
302 gchar *shortOpt, *option, *svalue;
305 index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
306 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
307 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
309 gtk_tree_model_get(store, &iter, 0, &option, 2, &shortOpt,
310 3, &ivalue, 4, &svalue, -1);
311 value = ghb_combo_value_new(index, option, shortOpt,
317 str = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
318 if (str == NULL) str = "";
319 value = ghb_combo_value_new(-1, str, str, str, -1);
322 else if (type == GTK_TYPE_SPIN_BUTTON)
325 ival = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
326 value = ghb_int64_value_new(ival);
328 else if (type == GTK_TYPE_HSCALE)
331 dval = gtk_range_get_value(GTK_RANGE(widget));
332 value = ghb_double_value_new(dval);
334 else if (type == GTK_TYPE_TEXT_VIEW)
336 GtkTextBuffer *buffer;
337 GtkTextIter start, end;
340 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
341 gtk_text_buffer_get_bounds(buffer, &start, &end);
342 str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
343 value = ghb_string_value_new(str);
346 else if (type == GTK_TYPE_LABEL)
349 str = gtk_label_get_text (GTK_LABEL(widget));
350 value = ghb_string_value_new(str);
354 g_debug("Attempt to set unknown widget type: %s\n", name);
362 ghb_widget_string(GtkWidget *widget)
367 value = ghb_widget_value(widget);
368 sval = ghb_value_string(value);
369 ghb_value_free(value);
374 ghb_widget_double(GtkWidget *widget)
379 value = ghb_widget_value(widget);
380 dval = ghb_value_double(value);
381 ghb_value_free(value);
386 ghb_widget_int64(GtkWidget *widget)
391 value = ghb_widget_value(widget);
392 ival = ghb_value_int64(value);
393 ghb_value_free(value);
398 ghb_widget_int(GtkWidget *widget)
403 value = ghb_widget_value(widget);
404 ival = (gint)ghb_value_int64(value);
405 ghb_value_free(value);
410 ghb_widget_index(GtkWidget *widget)
415 value = ghb_widget_value(widget);
416 if (value == NULL) return 0;
418 if (G_VALUE_TYPE(value) != ghb_combodata_get_type())
420 ghb_value_free(value);
423 cd = g_value_get_boxed(value);
425 ghb_value_free(value);
430 ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
432 const gchar *key = NULL;
435 if (widget == NULL) return;
436 g_debug("ghb_widget_to_setting");
437 // Find corresponding setting
438 key = get_setting_key(widget);
439 if (key == NULL) return;
440 value = ghb_widget_value(widget);
443 ghb_settings_take_value(settings, key, value);
447 g_debug("No value found for %s\n", key);
452 update_widget(GtkWidget *widget, const GValue *value)
459 type = G_VALUE_TYPE(value);
460 if (type == ghb_array_get_type() || type == ghb_dict_get_type())
462 if (value == NULL) return;
463 str = ghb_value_string(value);
464 ival = ghb_value_int(value);
465 dval = ghb_value_double(value);
466 type = GTK_OBJECT_TYPE(widget);
467 if (type == GTK_TYPE_ENTRY)
470 gtk_entry_set_text((GtkEntry*)widget, str);
472 else if (type == GTK_TYPE_RADIO_BUTTON)
474 g_debug("radio button");
475 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
477 else if (type == GTK_TYPE_CHECK_BUTTON)
479 g_debug("check button");
480 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
482 else if (type == GTK_TYPE_TOGGLE_ACTION)
484 g_debug("toggle action");
485 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(widget), ival);
487 else if (type == GTK_TYPE_CHECK_MENU_ITEM)
489 g_debug("check menu item");
490 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), ival);
492 else if (type == GTK_TYPE_COMBO_BOX)
498 gboolean foundit = FALSE;
500 g_debug("combo (%s)", str);
501 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
502 if (gtk_tree_model_get_iter_first (store, &iter))
506 gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
507 if (strcmp(shortOpt, str) == 0)
509 gtk_combo_box_set_active_iter (
510 GTK_COMBO_BOX(widget), &iter);
516 } while (gtk_tree_model_iter_next (store, &iter));
518 if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
522 gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
525 gtk_combo_box_set_active_iter (
526 GTK_COMBO_BOX(widget), &iter);
530 } while (gtk_tree_model_iter_next (store, &iter));
534 gtk_combo_box_set_active (GTK_COMBO_BOX(widget), 0);
537 else if (type == GTK_TYPE_COMBO_BOX_ENTRY)
543 gboolean foundit = FALSE;
545 g_debug("GTK_COMBO_BOX_ENTRY");
546 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
547 if (gtk_tree_model_get_iter_first (store, &iter))
551 gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
552 if (strcmp(shortOpt, str) == 0)
554 gtk_combo_box_set_active_iter (
555 GTK_COMBO_BOX(widget), &iter);
561 } while (gtk_tree_model_iter_next (store, &iter));
563 if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
567 gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
570 gtk_combo_box_set_active_iter (
571 GTK_COMBO_BOX(widget), &iter);
575 } while (gtk_tree_model_iter_next (store, &iter));
579 GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget)));
582 gtk_entry_set_text (entry, str);
586 else if (type == GTK_TYPE_SPIN_BUTTON)
588 g_debug("spin (%s)", str);
589 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), dval);
591 else if (type == GTK_TYPE_HSCALE)
594 gtk_range_set_value(GTK_RANGE(widget), dval);
596 else if (type == GTK_TYPE_TEXT_VIEW)
598 g_debug("textview (%s)", str);
599 GtkTextBuffer *buffer = gtk_text_view_get_buffer(
600 GTK_TEXT_VIEW(widget));
601 gtk_text_buffer_set_text (buffer, str, -1);
605 g_debug("Attempt to set unknown widget type");
611 ghb_ui_update(signal_user_data_t *ud, const gchar *name, const GValue *value)
615 if (name == NULL || value == NULL)
617 object = GHB_OBJECT(ud->builder, name);
620 g_debug("Failed to find widget for key: %s\n", name);
623 update_widget((GtkWidget*)object, value);
624 // Its possible the value hasn't changed. Since settings are only
625 // updated when the value changes, I'm initializing settings here as well.
626 ghb_widget_to_setting(ud->settings, (GtkWidget*)object);
638 struct x264_opt_map_s
647 static gchar *x264_ref_syns[] = {"ref", "frameref", NULL};
648 static gchar *x264_mixed_syns[] = {"mixed-refs", "mixed_refs", NULL};
649 static gchar *x264_bframes_syns[] = {"bframes", NULL};
650 static gchar *x264_direct_syns[] =
651 {"direct", "direct-pred", "direct_pred", NULL};
652 static gchar *x264_weightb_syns[] = {"weightb", "weight-b", "weight_b", NULL};
653 static gchar *x264_brdo_syns[] = {"brdo", "b-rdo", "b_rdo", NULL};
654 static gchar *x264_bime_syns[] = {"bime", NULL};
655 static gchar *x264_bpyramid_syns[] = {"b-pyramid", "b_pyramid", NULL};
656 static gchar *x264_me_syns[] = {"me", NULL};
657 static gchar *x264_merange_syns[] = {"merange", "me-range", "me_range", NULL};
658 static gchar *x264_subme_syns[] = {"subme", "subq", NULL};
659 static gchar *x264_analyse_syns[] = {"analyse", "partitions", NULL};
660 static gchar *x264_8x8dct_syns[] = {"8x8dct", NULL};
661 static gchar *x264_deblock_syns[] = {"deblock", "filter", NULL};
662 static gchar *x264_trellis_syns[] = {"trellis", NULL};
663 static gchar *x264_pskip_syns[] = {"no-fast-pskip", "no_fast_pskip", NULL};
664 static gchar *x264_decimate_syns[] =
665 {"no-dct-decimate", "no_dct_decimate", NULL};
666 static gchar *x264_cabac_syns[] = {"cabac", NULL};
669 find_syn_match(const gchar *opt, gchar **syns)
672 for (ii = 0; syns[ii] != NULL; ii++)
674 if (strcmp(opt, syns[ii]) == 0)
680 struct x264_opt_map_s x264_opt_map[] =
682 {x264_ref_syns, "x264_refs", "1", X264_OPT_INT},
683 {x264_mixed_syns, "x264_mixed_refs", "0", X264_OPT_BOOL},
684 {x264_bframes_syns, "x264_bframes", "0", X264_OPT_INT},
685 {x264_direct_syns, "x264_direct", "spatial", X264_OPT_COMBO},
686 {x264_weightb_syns, "x264_weighted_bframes", "0", X264_OPT_BOOL},
687 {x264_brdo_syns, "x264_brdo", "0", X264_OPT_BOOL},
688 {x264_bime_syns, "x264_bime", "0", X264_OPT_BOOL},
689 {x264_bpyramid_syns, "x264_bpyramid", "0", X264_OPT_BOOL},
690 {x264_me_syns, "x264_me", "hex", X264_OPT_COMBO},
691 {x264_merange_syns, "x264_merange", "16", X264_OPT_INT},
692 {x264_subme_syns, "x264_subme", "4", X264_OPT_COMBO},
693 {x264_analyse_syns, "x264_analyse", "some", X264_OPT_COMBO},
694 {x264_8x8dct_syns, "x264_8x8dct", "0", X264_OPT_BOOL},
695 {x264_deblock_syns, "x264_deblock_alpha", "0,0", X264_OPT_DEBLOCK},
696 {x264_deblock_syns, "x264_deblock_beta", "0,0", X264_OPT_DEBLOCK},
697 {x264_trellis_syns, "x264_trellis", "0", X264_OPT_COMBO},
698 {x264_pskip_syns, "x264_no_fast_pskip", "0", X264_OPT_BOOL},
699 {x264_decimate_syns, "x264_no_dct_decimate", "0", X264_OPT_BOOL},
700 {x264_cabac_syns, "x264_cabac", "1", X264_OPT_BOOL},
702 #define X264_OPT_MAP_SIZE (sizeof(x264_opt_map)/sizeof(struct x264_opt_map_s))
705 x264_opt_get_default(const gchar *opt)
708 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
710 if (find_syn_match(opt, x264_opt_map[jj].opt_syns) >= 0)
712 return x264_opt_map[jj].def_val;
719 x264_update_int(signal_user_data_t *ud, const gchar *name, const gchar *val)
723 if (val == NULL) return;
724 ival = g_strtod (val, NULL);
725 ghb_ui_update(ud, name, ghb_int64_value(ival));
728 static gchar *true_str[] =
737 str_is_true(const gchar *str)
740 for (ii = 0; true_str[ii]; ii++)
742 if (g_ascii_strcasecmp(str, true_str[ii]) == 0)
749 x264_update_bool(signal_user_data_t *ud, const gchar *name, const gchar *val)
752 ghb_ui_update(ud, name, ghb_boolean_value(1));
754 ghb_ui_update(ud, name, ghb_boolean_value(str_is_true(val)));
758 x264_update_combo(signal_user_data_t *ud, const gchar *name, const gchar *val)
764 gboolean foundit = FALSE;
767 if (val == NULL) return;
768 widget = GHB_WIDGET(ud->builder, name);
771 g_debug("Failed to find widget for key: %s\n", name);
774 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
775 if (gtk_tree_model_get_iter_first (store, &iter))
779 gtk_tree_model_get(store, &iter, 2, &shortOpt, 3, &ivalue, -1);
780 if (strcmp(shortOpt, val) == 0)
782 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
788 } while (gtk_tree_model_iter_next (store, &iter));
792 if (gtk_tree_model_get_iter_first (store, &iter))
796 gtk_tree_model_get(store, &iter, 2, &shortOpt, 3, &ivalue, -1);
797 if (strcmp(shortOpt, "custom") == 0)
799 gtk_list_store_set(GTK_LIST_STORE(store), &iter, 4, val, -1);
800 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
806 } while (gtk_tree_model_iter_next (store, &iter));
809 // Its possible the value hasn't changed. Since settings are only
810 // updated when the value changes, I'm initializing settings here as well.
811 ghb_widget_to_setting(ud->settings, widget);
815 x264_update_deblock(signal_user_data_t *ud, const gchar *xval)
817 gdouble avalue, bvalue;
822 if (xval == NULL) return;
823 val = g_strdup(xval);
827 gchar *pos = strchr(val, ',');
833 avalue = g_strtod (val, &end);
836 bvalue = g_strtod (bval, &end);
840 ghb_ui_update(ud, "x264_deblock_alpha", ghb_int64_value(avalue));
841 ghb_ui_update(ud, "x264_deblock_beta", ghb_int64_value(bvalue));
845 ghb_x264_parse_options(signal_user_data_t *ud, const gchar *options)
847 gchar **split = g_strsplit(options, ":", -1);
848 if (split == NULL) return;
853 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
854 x264_opt_map[jj].found = FALSE;
856 for (ii = 0; split[ii] != NULL; ii++)
859 gchar *pos = strchr(split[ii], '=');
865 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
867 if (find_syn_match(split[ii], x264_opt_map[jj].opt_syns) >= 0)
869 x264_opt_map[jj].found = TRUE;
870 switch(x264_opt_map[jj].type)
873 x264_update_int(ud, x264_opt_map[jj].name, val);
876 x264_update_bool(ud, x264_opt_map[jj].name, val);
879 x264_update_combo(ud, x264_opt_map[jj].name, val);
881 case X264_OPT_DEBLOCK:
882 // dirty little hack. mark deblock_beta found as well
883 x264_opt_map[jj+1].found = TRUE;
884 x264_update_deblock(ud, val);
891 // For any options not found in the option string, set ui to
893 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
895 if (!x264_opt_map[jj].found)
897 gchar *val = strdup(x264_opt_map[jj].def_val);
898 switch(x264_opt_map[jj].type)
901 x264_update_int(ud, x264_opt_map[jj].name, val);
904 x264_update_bool(ud, x264_opt_map[jj].name, val);
907 x264_update_combo(ud, x264_opt_map[jj].name, val);
909 case X264_OPT_DEBLOCK:
910 x264_update_deblock(ud, val);
913 x264_opt_map[jj].found = TRUE;
921 get_deblock_val(signal_user_data_t *ud)
925 alpha = ghb_settings_get_string(ud->settings, "x264_deblock_alpha");
926 beta = ghb_settings_get_string(ud->settings, "x264_deblock_beta");
927 result = g_strdup_printf("%s,%s", alpha, beta);
934 ghb_x264_opt_update(signal_user_data_t *ud, GtkWidget *widget)
937 const gchar *name = gtk_widget_get_name(widget);
938 gchar **opt_syns = NULL;
939 const gchar *def_val = NULL;
942 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
944 if (strcmp(name, x264_opt_map[jj].name) == 0)
946 // found the options that needs updating
947 opt_syns = x264_opt_map[jj].opt_syns;
948 def_val = x264_opt_map[jj].def_val;
949 type = x264_opt_map[jj].type;
953 if (opt_syns != NULL)
955 GString *x264opts = g_string_new("");
957 gchar **split = NULL;
959 gboolean foundit = FALSE;
961 options = ghb_settings_get_string(ud->settings, "x264_options");
964 split = g_strsplit(options, ":", -1);
967 for (ii = 0; split && split[ii] != NULL; ii++)
971 gchar *pos = strchr(split[ii], '=');
977 syn = find_syn_match(split[ii], opt_syns);
979 { // Updating this option
982 if (type == X264_OPT_DEBLOCK)
983 val = get_deblock_val(ud);
987 gval = ghb_widget_value(widget);
988 if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
990 if (ghb_value_boolean(gval))
997 val = ghb_widget_string(widget);
999 ghb_value_free(gval);
1001 if (strcmp(def_val, val) != 0)
1003 g_string_append_printf(x264opts, "%s=%s:", opt_syns[syn], val);
1007 else if (val != NULL)
1008 g_string_append_printf(x264opts, "%s=%s:", split[ii], val);
1010 g_string_append_printf(x264opts, "%s:", split[ii]);
1013 if (split) g_strfreev(split);
1017 if (type == X264_OPT_DEBLOCK)
1018 val = get_deblock_val(ud);
1022 gval = ghb_widget_value(widget);
1023 if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
1025 if (ghb_value_boolean(gval))
1026 val = g_strdup("1");
1028 val = g_strdup("0");
1032 val = ghb_widget_string(widget);
1034 ghb_value_free(gval);
1036 if (strcmp(def_val, val) != 0)
1038 g_string_append_printf(x264opts, "%s=%s:", opt_syns[0], val);
1042 // Update the options value
1043 // strip the trailing ":"
1046 result = g_string_free(x264opts, FALSE);
1047 len = strlen(result);
1048 if (len > 0) result[len - 1] = 0;
1050 sopts = ghb_sanitize_x264opts(ud, result);
1051 ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
1052 ghb_x264_parse_options(ud, sopts);
1059 x264_remove_opt(gchar **opts, gchar **opt_syns)
1062 for (ii = 0; opts[ii] != NULL; ii++)
1065 opt = g_strdup(opts[ii]);
1066 gchar *pos = strchr(opt, '=');
1071 if (find_syn_match(opt, opt_syns) >= 0)
1080 // Construct the x264 options string
1081 // The result is allocated, so someone must free it at some point.
1083 ghb_sanitize_x264opts(signal_user_data_t *ud, const gchar *options)
1085 GString *x264opts = g_string_new("");
1086 gchar **split = g_strsplit(options, ":", -1);
1088 // Remove entries that match the defaults
1090 for (ii = 0; split[ii] != NULL; ii++)
1093 gchar *opt = g_strdup(split[ii]);
1094 gchar *pos = strchr(opt, '=');
1104 const gchar *def_val = x264_opt_get_default(opt);
1105 if (strcmp(val, def_val) == 0)
1107 // Matches the default, so remove it
1112 gint refs = ghb_settings_get_int(ud->settings, "x264_refs");
1115 x264_remove_opt(split, x264_mixed_syns);
1117 gint subme = ghb_settings_get_int(ud->settings, "x264_subme");
1120 x264_remove_opt(split, x264_brdo_syns);
1122 gint bframes = ghb_settings_get_int(ud->settings, "x264_bframes");
1125 x264_remove_opt(split, x264_weightb_syns);
1126 x264_remove_opt(split, x264_brdo_syns);
1127 x264_remove_opt(split, x264_bime_syns);
1131 x264_remove_opt(split, x264_bpyramid_syns);
1133 gchar *me = ghb_settings_get_string(ud->settings, "x264_me");
1134 if (!(strcmp(me, "umh") == 0 || strcmp(me, "esa") == 0))
1136 x264_remove_opt(split, x264_merange_syns);
1139 if (!ghb_settings_get_boolean(ud->settings, "x264_cabac"))
1141 x264_remove_opt(split, x264_trellis_syns);
1143 gint analyse = ghb_settings_get_int(ud->settings, "x264_analyse");
1146 x264_remove_opt(split, x264_direct_syns);
1148 for (ii = 0; split[ii] != NULL; ii++)
1150 if (split[ii][0] != 0)
1151 g_string_append_printf(x264opts, "%s:", split[ii]);
1154 // strip the trailing ":"
1157 result = g_string_free(x264opts, FALSE);
1158 len = strlen(result);
1159 if (len > 0) result[len - 1] = 0;
1164 ghb_pref_acount(GValue *settings)
1167 acodec = ghb_settings_get_value(settings, "pref_audio_codec");
1168 return ghb_array_len(acodec);
1172 ghb_pref_acodec(GValue *settings, gint index)
1177 acodec = ghb_settings_get_value(settings, "pref_audio_codec");
1178 count = ghb_array_len(acodec);
1181 return ghb_value_int(ghb_array_get_nth(acodec, index));
1185 ghb_pref_bitrate(GValue *settings, gint index)
1190 bitrate = ghb_settings_get_value(settings, "pref_audio_bitrate");
1191 count = ghb_array_len(bitrate);
1194 return ghb_value_int(ghb_array_get_nth(bitrate, index));
1198 ghb_pref_rate(GValue *settings, gint index)
1203 rate = ghb_settings_get_value(settings, "pref_audio_rate");
1204 count = ghb_array_len(rate);
1207 return ghb_value_int(ghb_array_get_nth(rate, index));
1211 ghb_pref_mix(GValue *settings, gint index)
1216 mix = ghb_settings_get_value(settings, "pref_audio_mix");
1217 count = ghb_array_len(mix);
1220 return ghb_value_int(ghb_array_get_nth(mix, index));
1224 ghb_pref_drc(GValue *settings, gint index)
1229 drc = ghb_settings_get_value(settings, "pref_audio_drc");
1230 count = ghb_array_len(drc);
1233 return ghb_value_double(ghb_array_get_nth(drc, index));