OSDN Git Service

LinGui: trim both callbacks.c and settings.c. Move code to x264handler
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 26 Sep 2008 18:16:00 +0000 (18:16 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 26 Sep 2008 18:16:00 +0000 (18:16 +0000)
git-svn-id: svn://localhost/HandBrake/trunk@1776 b64f7644-9d1e-0410-96f1-a4d463321fa5

gtk/src/Makefile.am
gtk/src/callbacks.c
gtk/src/callbacks.h
gtk/src/main.c
gtk/src/settings.c
gtk/src/settings.h
gtk/src/x264handler.c [new file with mode: 0644]
gtk/src/x264handler.h [new file with mode: 0644]

index 24d3866..7d4d1d3 100644 (file)
@@ -90,6 +90,8 @@ ghb_SOURCES = \
        queuehandler.h \
        audiohandler.c \
        audiohandler.h \
+       x264handler.c \
+       x264handler.h \
        main.c \
        settings.c \
        settings.h \
index a263432..2fc7e39 100644 (file)
@@ -210,14 +210,14 @@ ghb_check_all_depencencies(signal_user_data_t *ud)
        }
 }
 
-static void
-clear_presets_selection(signal_user_data_t *ud)
+void
+ghb_clear_presets_selection(signal_user_data_t *ud)
 {
        GtkTreeView *treeview;
        GtkTreeSelection *selection;
        
        if (ud->dont_clear_presets) return;
-       g_debug("clear_presets_selection()");
+       g_debug("ghb_clear_presets_selection()");
        treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
        selection = gtk_tree_view_get_selection (treeview);
        gtk_tree_selection_unselect_all (selection);
@@ -839,7 +839,7 @@ container_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        update_destination_extension(ud);
        ghb_check_dependency(ud, widget);
        update_acodec_combo(ud);
-       clear_presets_selection(ud);
+       ghb_clear_presets_selection(ud);
 
        audio_list = ghb_settings_get_value(ud->settings, "audio_list");
        if (ghb_ac3_in_audio_list (audio_list))
@@ -1045,18 +1045,11 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 }
 
 void
-generic_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       g_debug("generic_widget_changed_cb ()");
-       ghb_check_dependency(ud, widget);
-}
-
-void
 setting_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
        ghb_check_dependency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_clear_presets_selection(ud);
 }
 
 static void
@@ -1117,7 +1110,8 @@ http_opt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
        ghb_check_dependency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_clear_presets_selection(ud);
+       // AC3 is not allowed when Web optimized
        ghb_grey_combo_options (ud->builder);
 }
 
@@ -1128,7 +1122,7 @@ vcodec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 
        ghb_widget_to_setting(ud->settings, widget);
        ghb_check_dependency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_clear_presets_selection(ud);
        ghb_vquality_range(ud, &vqmin, &vqmax);
        GtkWidget *qp = GHB_WIDGET(ud->builder, "video_quality");
        gtk_range_set_range (GTK_RANGE(qp), vqmin, vqmax);
@@ -1141,7 +1135,7 @@ target_size_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        g_debug("setting_widget_changed_cb () %s", name);
        ghb_widget_to_setting(ud->settings, widget);
        ghb_check_dependency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_clear_presets_selection(ud);
        if (ghb_settings_get_boolean(ud->settings, "vquality_type_target"))
        {
                gint titleindex;
@@ -1265,7 +1259,7 @@ scale_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        g_debug("scale_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
        ghb_check_dependency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_clear_presets_selection(ud);
        ghb_set_scale (ud, GHB_SCALE_KEEP_NONE);
        update_preview = TRUE;
        
@@ -1299,81 +1293,6 @@ generic_entry_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
        }
 }
 
-gboolean
-generic_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, 
-       signal_user_data_t *ud)
-{
-       g_debug("generic_focus_out_cb ()");
-       ghb_widget_to_setting(ud->settings, widget);
-       return FALSE;
-}
-
-// Flag needed to prevent x264 options processing from chasing its tail
-static gboolean ignore_options_update = FALSE;
-
-void
-x264_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       ghb_widget_to_setting(ud->settings, widget);
-       if (!ignore_options_update)
-       {
-               ignore_options_update = TRUE;
-               ghb_x264_opt_update(ud, widget);
-               ignore_options_update = FALSE;
-       }
-       ghb_check_dependency(ud, widget);
-       clear_presets_selection(ud);
-}
-
-void
-x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       g_debug("x264_entry_changed_cb ()");
-       if (!ignore_options_update)
-       {
-               GtkWidget *textview;
-               gchar *options;
-
-               textview = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264_options"));
-               ghb_widget_to_setting(ud->settings, textview);
-               options = ghb_settings_get_string(ud->settings, "x264_options");
-               ignore_options_update = TRUE;
-               ghb_x264_parse_options(ud, options);
-               if (!GTK_WIDGET_HAS_FOCUS(textview))
-               {
-                       gchar *sopts;
-
-                       sopts = ghb_sanitize_x264opts(ud, options);
-                       ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
-                       ghb_x264_parse_options(ud, sopts);
-                       g_free(sopts);
-               }
-               g_free(options);
-               ignore_options_update = FALSE;
-       }
-}
-
-gboolean
-x264_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, 
-       signal_user_data_t *ud)
-{
-       gchar *options, *sopts;
-
-       ghb_widget_to_setting(ud->settings, widget);
-       options = ghb_settings_get_string(ud->settings, "x264_options");
-       sopts = ghb_sanitize_x264opts(ud, options);
-       ignore_options_update = TRUE;
-       if (sopts != NULL)
-       {
-               ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
-               ghb_x264_parse_options(ud, sopts);
-       }
-       g_free(options);
-       g_free(sopts);
-       ignore_options_update = FALSE;
-       return FALSE;
-}
-
 void
 ghb_presets_list_update(signal_user_data_t *ud)
 {
@@ -1550,18 +1469,6 @@ presets_restore_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 }
 
 void
-prefs_dialog_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       GtkWidget *dialog;
-       GtkResponseType response;
-
-       g_debug("prefs_dialog_cb ()");
-       dialog = GHB_WIDGET(ud->builder, "prefs_dialog");
-       response = gtk_dialog_run(GTK_DIALOG(dialog));
-       gtk_widget_hide(dialog);
-}
-
-void
 presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkTreeView *treeview;
@@ -1696,6 +1603,18 @@ presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_
        }
 }
 
+void
+prefs_dialog_cb(GtkWidget *xwidget, signal_user_data_t *ud)
+{
+       GtkWidget *dialog;
+       GtkResponseType response;
+
+       g_debug("prefs_dialog_cb ()");
+       dialog = GHB_WIDGET(ud->builder, "prefs_dialog");
+       response = gtk_dialog_run(GTK_DIALOG(dialog));
+       gtk_widget_hide(dialog);
+}
+
 gboolean
 ghb_message_dialog(GtkMessageType type, const gchar *message, const gchar *no, const gchar *yes)
 {
index d49144d..7bc7936 100644 (file)
@@ -46,6 +46,7 @@ gboolean ghb_reload_queue(signal_user_data_t *ud);
 gboolean ghb_cancel_encode(const gchar *extra_msg);
 GValue* ghb_start_next_job(signal_user_data_t *ud, gboolean find_first);
 void ghb_check_dependency(signal_user_data_t *ud, GtkWidget *widget);
+void ghb_clear_presets_selection(signal_user_data_t *ud);
 
 #endif // _CALLBACKS_H_
 
index 94e5386..52c581c 100644 (file)
@@ -42,6 +42,7 @@
 #include "values.h"
 #include "icons.h"
 #include "callbacks.h"
+#include "x264handler.h"
 #include "settings.h"
 #include "resources.h"
 #include "presets.h"
index d108814..e3bec95 100644 (file)
@@ -587,538 +587,6 @@ ghb_ui_update(signal_user_data_t *ud, const gchar *name, const GValue *value)
        return 0;
 }
 
-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", "mixed_refs", NULL};
-static gchar *x264_bframes_syns[] = {"bframes", NULL};
-static gchar *x264_direct_syns[] = 
-       {"direct", "direct-pred", "direct_pred", NULL};
-static gchar *x264_weightb_syns[] = {"weightb", "weight-b", "weight_b", NULL};
-static gchar *x264_brdo_syns[] = {"brdo", "b-rdo", "b_rdo", NULL};
-static gchar *x264_bime_syns[] = {"bime", NULL};
-static gchar *x264_bpyramid_syns[] = {"b-pyramid", "b_pyramid", NULL};
-static gchar *x264_me_syns[] = {"me", NULL};
-static gchar *x264_merange_syns[] = {"merange", "me-range", "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", "no_fast_pskip", NULL};
-static gchar *x264_decimate_syns[] = 
-       {"no-dct-decimate", "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", "6", 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)
-{
-       gint ival;
-
-       if (val == NULL) return;
-       ival = g_strtod (val, NULL);
-       ghb_ui_update(ud, name, ghb_int64_value(ival));
-}
-
-static gchar *true_str[] =
-{
-       "true",
-       "yes",
-       "1",
-       NULL
-};
-
-static gboolean 
-str_is_true(const gchar *str)
-{
-       gint ii;
-       for (ii = 0; true_str[ii]; ii++)
-       {
-               if (g_ascii_strcasecmp(str, true_str[ii]) == 0)
-                       return TRUE;
-       }
-       return FALSE;
-}
-
-static void
-x264_update_bool(signal_user_data_t *ud, const gchar *name, const gchar *val)
-{
-       if (val == NULL)
-               ghb_ui_update(ud, name, ghb_boolean_value(1));
-       else
-               ghb_ui_update(ud, name, ghb_boolean_value(str_is_true(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(ud, "x264_deblock_alpha", ghb_int64_value(avalue));
-       ghb_ui_update(ud, "x264_deblock_beta", ghb_int64_value(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)
-{
-       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);
-       g_free(alpha);
-       g_free(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("");
-               gchar *options;
-               gchar **split = NULL;
-               gint ii;
-               gboolean foundit = FALSE;
-
-               options = ghb_settings_get_string(ud->settings, "x264_options");
-               if (options)
-               {
-                       split = g_strsplit(options, ":", -1);
-                       g_free(options);
-               }
-               for (ii = 0; split && 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
-                               {
-                                       GValue *gval;
-                                       gval = ghb_widget_value(widget);
-                                       if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
-                                       {
-                                               if (ghb_value_boolean(gval))
-                                                       val = g_strdup("1");
-                                               else
-                                                       val = g_strdup("0");
-                                       }
-                                       else
-                                       {
-                                               val = ghb_widget_string(widget);
-                                       }
-                                       ghb_value_free(gval);
-                               }
-                               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 (split) g_strfreev(split);
-               if (!foundit)
-               {
-                       gchar *val;
-                       if (type == X264_OPT_DEBLOCK)
-                               val = get_deblock_val(ud);
-                       else
-                       {
-                               GValue *gval;
-                               gval = ghb_widget_value(widget);
-                               if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
-                               {
-                                       if (ghb_value_boolean(gval))
-                                               val = g_strdup("1");
-                                       else
-                                               val = g_strdup("0");
-                               }
-                               else
-                               {
-                                       val = ghb_widget_string(widget);
-                               }
-                               ghb_value_free(gval);
-                       }
-                       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;
-               gchar *sopts;
-               sopts = ghb_sanitize_x264opts(ud, result);
-               ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
-               ghb_x264_parse_options(ud, sopts);
-               g_free(sopts);
-               g_free(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;
-
-       subme = ghb_lookup_combo_int("x264_subme",
-                                       ghb_settings_get_value(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);
-               x264_remove_opt(split, x264_direct_syns);
-       }
-       if (bframes <= 1)
-       {
-               x264_remove_opt(split, x264_bpyramid_syns);
-       }
-       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);
-       }
-       g_free(me);
-       if (!ghb_settings_get_boolean(ud->settings, "x264_cabac"))
-       {
-               x264_remove_opt(split, x264_trellis_syns);
-       }
-       for (ii = 0; split[ii] != NULL; ii++)
-       {
-               if (split[ii][0] != 0)
-                       g_string_append_printf(x264opts, "%s:", split[ii]);
-       }
-       g_strfreev(split);
-       // 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;
-}
-
 gint
 ghb_pref_acount(GValue *settings)
 {
index ca3ffa1..69a79c2 100644 (file)
@@ -94,9 +94,6 @@ void ghb_widget_to_setting(GValue *settings, GtkWidget *widget);
 int ghb_ui_update(
        signal_user_data_t *ud, const gchar *name, const GValue *value);
 
-void ghb_x264_parse_options(signal_user_data_t *ud, const gchar *options);
-void ghb_x264_opt_update(signal_user_data_t *ud, GtkWidget *widget);
-gchar* ghb_sanitize_x264opts(signal_user_data_t *ud, const gchar *options);
 
 gint ghb_pref_acount(GValue *settings);
 gint ghb_pref_acodec(GValue *settings, gint index);
diff --git a/gtk/src/x264handler.c b/gtk/src/x264handler.c
new file mode 100644 (file)
index 0000000..4a75520
--- /dev/null
@@ -0,0 +1,620 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * x264handler.c
+ * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
+ * 
+ * x264handler.c is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <gtk/gtk.h>
+#include <string.h>
+#include "settings.h"
+#include "values.h"
+#include "callbacks.h"
+#include "x264handler.h"
+
+static void x264_opt_update(signal_user_data_t *ud, GtkWidget *widget);
+static gchar* sanitize_x264opts(signal_user_data_t *ud, const gchar *options);
+
+// Flag needed to prevent x264 options processing from chasing its tail
+static gboolean ignore_options_update = FALSE;
+
+void
+x264_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+       ghb_widget_to_setting(ud->settings, widget);
+       if (!ignore_options_update)
+       {
+               ignore_options_update = TRUE;
+               x264_opt_update(ud, widget);
+               ignore_options_update = FALSE;
+       }
+       ghb_check_dependency(ud, widget);
+       ghb_clear_presets_selection(ud);
+}
+
+void
+x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+       g_debug("x264_entry_changed_cb ()");
+       if (!ignore_options_update)
+       {
+               GtkWidget *textview;
+               gchar *options;
+
+               textview = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264_options"));
+               ghb_widget_to_setting(ud->settings, textview);
+               options = ghb_settings_get_string(ud->settings, "x264_options");
+               ignore_options_update = TRUE;
+               ghb_x264_parse_options(ud, options);
+               if (!GTK_WIDGET_HAS_FOCUS(textview))
+               {
+                       gchar *sopts;
+
+                       sopts = sanitize_x264opts(ud, options);
+                       ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
+                       ghb_x264_parse_options(ud, sopts);
+                       g_free(sopts);
+               }
+               g_free(options);
+               ignore_options_update = FALSE;
+       }
+}
+
+gboolean
+x264_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, 
+       signal_user_data_t *ud)
+{
+       gchar *options, *sopts;
+
+       ghb_widget_to_setting(ud->settings, widget);
+       options = ghb_settings_get_string(ud->settings, "x264_options");
+       sopts = sanitize_x264opts(ud, options);
+       ignore_options_update = TRUE;
+       if (sopts != NULL)
+       {
+               ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
+               ghb_x264_parse_options(ud, sopts);
+       }
+       g_free(options);
+       g_free(sopts);
+       ignore_options_update = FALSE;
+       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", "mixed_refs", NULL};
+static gchar *x264_bframes_syns[] = {"bframes", NULL};
+static gchar *x264_direct_syns[] = 
+       {"direct", "direct-pred", "direct_pred", NULL};
+static gchar *x264_weightb_syns[] = {"weightb", "weight-b", "weight_b", NULL};
+static gchar *x264_brdo_syns[] = {"brdo", "b-rdo", "b_rdo", NULL};
+static gchar *x264_bime_syns[] = {"bime", NULL};
+static gchar *x264_bpyramid_syns[] = {"b-pyramid", "b_pyramid", NULL};
+static gchar *x264_me_syns[] = {"me", NULL};
+static gchar *x264_merange_syns[] = {"merange", "me-range", "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", "no_fast_pskip", NULL};
+static gchar *x264_decimate_syns[] = 
+       {"no-dct-decimate", "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", "6", 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)
+{
+       gint ival;
+
+       if (val == NULL) return;
+       ival = g_strtod (val, NULL);
+       ghb_ui_update(ud, name, ghb_int64_value(ival));
+}
+
+static gchar *true_str[] =
+{
+       "true",
+       "yes",
+       "1",
+       NULL
+};
+
+static gboolean 
+str_is_true(const gchar *str)
+{
+       gint ii;
+       for (ii = 0; true_str[ii]; ii++)
+       {
+               if (g_ascii_strcasecmp(str, true_str[ii]) == 0)
+                       return TRUE;
+       }
+       return FALSE;
+}
+
+static void
+x264_update_bool(signal_user_data_t *ud, const gchar *name, const gchar *val)
+{
+       if (val == NULL)
+               ghb_ui_update(ud, name, ghb_boolean_value(1));
+       else
+               ghb_ui_update(ud, name, ghb_boolean_value(str_is_true(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(ud, "x264_deblock_alpha", ghb_int64_value(avalue));
+       ghb_ui_update(ud, "x264_deblock_beta", ghb_int64_value(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)
+{
+       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);
+       g_free(alpha);
+       g_free(beta);
+       return result;
+}
+
+static void
+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("");
+               gchar *options;
+               gchar **split = NULL;
+               gint ii;
+               gboolean foundit = FALSE;
+
+               options = ghb_settings_get_string(ud->settings, "x264_options");
+               if (options)
+               {
+                       split = g_strsplit(options, ":", -1);
+                       g_free(options);
+               }
+               for (ii = 0; split && 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
+                               {
+                                       GValue *gval;
+                                       gval = ghb_widget_value(widget);
+                                       if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
+                                       {
+                                               if (ghb_value_boolean(gval))
+                                                       val = g_strdup("1");
+                                               else
+                                                       val = g_strdup("0");
+                                       }
+                                       else
+                                       {
+                                               val = ghb_widget_string(widget);
+                                       }
+                                       ghb_value_free(gval);
+                               }
+                               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 (split) g_strfreev(split);
+               if (!foundit)
+               {
+                       gchar *val;
+                       if (type == X264_OPT_DEBLOCK)
+                               val = get_deblock_val(ud);
+                       else
+                       {
+                               GValue *gval;
+                               gval = ghb_widget_value(widget);
+                               if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
+                               {
+                                       if (ghb_value_boolean(gval))
+                                               val = g_strdup("1");
+                                       else
+                                               val = g_strdup("0");
+                               }
+                               else
+                               {
+                                       val = ghb_widget_string(widget);
+                               }
+                               ghb_value_free(gval);
+                       }
+                       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;
+               gchar *sopts;
+               sopts = sanitize_x264opts(ud, result);
+               ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
+               ghb_x264_parse_options(ud, sopts);
+               g_free(sopts);
+               g_free(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.
+static gchar*
+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;
+
+       subme = ghb_settings_combo_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);
+               x264_remove_opt(split, x264_direct_syns);
+       }
+       if (bframes <= 1)
+       {
+               x264_remove_opt(split, x264_bpyramid_syns);
+       }
+       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);
+       }
+       g_free(me);
+       if (!ghb_settings_get_boolean(ud->settings, "x264_cabac"))
+       {
+               x264_remove_opt(split, x264_trellis_syns);
+       }
+       for (ii = 0; split[ii] != NULL; ii++)
+       {
+               if (split[ii][0] != 0)
+                       g_string_append_printf(x264opts, "%s:", split[ii]);
+       }
+       g_strfreev(split);
+       // 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;
+}
+
diff --git a/gtk/src/x264handler.h b/gtk/src/x264handler.h
new file mode 100644 (file)
index 0000000..89e906a
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * x264handler.h
+ * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
+ * 
+ * x264handler.h is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ * 
+ * callbacks.h is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with callbacks.h.  If not, write to:
+ *     The Free Software Foundation, Inc.,
+ *     51 Franklin Street, Fifth Floor
+ *     Boston, MA  02110-1301, USA.
+ */
+
+#if !defined(_X264HANDLER_H_)
+#define _X264HANDLER_H_
+
+#include "settings.h"
+
+void ghb_x264_parse_options(signal_user_data_t *ud, const gchar *options);
+
+#endif // _X264HANDLER_H_