summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2008-08-07 17:43:55 +0000
committerjstebbins <[email protected]>2008-08-07 17:43:55 +0000
commit752317f0446985db9179dcc975f10652400af589 (patch)
tree335e0f670d4e88d5b9259fdec9bdc54b07b6a5a0
parentc8ed1a0c1534761b2081f6c7ea71bf7c4a698d78 (diff)
LinGui: change how x264 options are handled
- there is now one preset key that contains the option string - options displayed in widgets and entry box stay reflect each other - enlarged the entry box so all options can be seen git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1614 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--gtk/src/callbacks.c66
-rw-r--r--gtk/src/ghb.ui107
-rw-r--r--gtk/src/hb-backend.c114
-rw-r--r--gtk/src/internal_defaults38
-rw-r--r--gtk/src/internal_defaults.h38
-rw-r--r--gtk/src/main.c13
-rw-r--r--gtk/src/settings.c512
-rw-r--r--gtk/src/settings.h3
-rwxr-xr-xgtk/src/standard_presets176
9 files changed, 697 insertions, 370 deletions
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c
index 78196b2f1..8c1088f0b 100644
--- a/gtk/src/callbacks.c
+++ b/gtk/src/callbacks.c
@@ -70,7 +70,6 @@ static dependency_t dep_map[] =
{"vquality_type_target", "video_target_size", "enable", FALSE},
{"vquality_type_constant", "video_quality", "enable", FALSE},
{"vquality_type_constant", "constant_rate_factor", "enable", FALSE},
- {"vquality_type_constant", "x264_trellis", "enable", TRUE},
{"vquality_type_constant", "two_pass", "enable", TRUE},
{"vquality_type_constant", "turbo", "enable", TRUE},
{"two_pass", "turbo", "enable", FALSE},
@@ -131,7 +130,6 @@ dep_check(signal_user_data_t *ud, const gchar *name)
{
GtkWidget *widget;
GObject *dep_object;
- gchar *value;
int ii;
int count = sizeof(dep_map) / sizeof(dependency_t);
gboolean result = TRUE;
@@ -143,17 +141,22 @@ dep_check(signal_user_data_t *ud, const gchar *name)
{
widget = GHB_WIDGET(ud->builder, dep_map[ii].widget_name);
dep_object = gtk_builder_get_object(ud->builder, dep_map[ii].dep_name);
- value = ghb_widget_short_opt(widget);
- if (dep_object == NULL || widget == NULL)
+ if (dep_object == NULL)
{
g_message("Failed to find widget\n");
}
else
{
+ gchar *value;
gint jj = 0;
gchar **values = g_strsplit(dep_map[ii].enable_value, "|", 10);
gboolean sensitive = FALSE;
+ if (widget)
+ value = ghb_widget_short_opt(widget);
+ else
+ value = g_strdup( ghb_settings_get_short_opt(
+ ud->settings, dep_map[ii].widget_name));
while (values && values[jj])
{
if (values[jj][0] == '>')
@@ -186,8 +189,8 @@ dep_check(signal_user_data_t *ud, const gchar *name)
sensitive = dep_map[ii].disable_if_equal ^ sensitive;
if (!sensitive) result = FALSE;
g_strfreev (values);
+ g_free(value);
}
- g_free(value);
}
}
return result;
@@ -1476,6 +1479,59 @@ generic_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
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;
+ }
+ check_depencency(ud, widget);
+ clear_presets_selection(ud);
+}
+
+void
+x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("x264_entry_changed_cb ()\n");
+ if (!ignore_options_update)
+ {
+ GtkWidget *textview;
+ textview = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264_options"));
+ ghb_widget_to_setting(ud->settings, textview);
+ const gchar *options;
+ options = ghb_settings_get_string(ud->settings, "x264_options");
+ ignore_options_update = TRUE;
+ ghb_x264_parse_options(ud, options);
+ ignore_options_update = FALSE;
+ }
+}
+
+gboolean
+x264_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
+ signal_user_data_t *ud)
+{
+ ghb_widget_to_setting(ud->settings, widget);
+ gchar *options;
+ options = (gchar*)ghb_settings_get_string(ud->settings, "x264_options");
+ options = ghb_sanitize_x264opts(ud, options);
+ ignore_options_update = TRUE;
+ if (options != NULL)
+ {
+ ghb_ui_update(ud, "x264_options", options);
+ ghb_x264_parse_options(ud, options);
+ g_free(options);
+ }
+ ignore_options_update = FALSE;
+ return FALSE;
+}
+
static void
clear_audio_list(signal_user_data_t *ud)
{
diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui
index c51e04be7..d84352911 100644
--- a/gtk/src/ghb.ui
+++ b/gtk/src/ghb.ui
@@ -2671,7 +2671,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Selects the number of reference frames that can be used. Slows down encoding. Good typical values are 3 to 5. Animation can benefit from more (8 to 10).</property>
<property name="adjustment">adjustment8</property>
- <signal handler="setting_widget_changed_cb" name="value_changed"/>
+ <signal handler="x264_widget_changed_cb" name="value_changed"/>
</object>
<packing>
<property name="expand">False</property>
@@ -2689,7 +2689,7 @@
<property name="label" translatable="yes">Mixed References</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
</object>
<packing>
<property name="expand">False</property>
@@ -2704,7 +2704,7 @@
<object class="GtkLabel" id="label50">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">&lt;b&gt;Refernce Frames&lt;/b&gt;</property>
+ <property name="label" translatable="yes">&lt;b&gt;Reference Frames&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
@@ -2762,7 +2762,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Sane values are 1-6. B-Frames are smaller than other frames, so they let you pack in more quality at the same bitrate. Use more of them with animated material: 9-16.</property>
<property name="adjustment">adjustment9</property>
- <signal handler="setting_widget_changed_cb" name="value_changed"/>
+ <signal handler="x264_widget_changed_cb" name="value_changed"/>
</object>
</child>
</object>
@@ -2802,7 +2802,7 @@
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">This option can improve compression efficiency. </property>
- <signal handler="setting_widget_changed_cb" name="changed"/>
+ <signal handler="x264_widget_changed_cb" name="changed"/>
</object>
</child>
</object>
@@ -2816,6 +2816,26 @@
<property name="position">1</property>
</packing>
</child>
+
+ <child>
+ <object class="GtkTable" id="table8">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+
+ <child>
+ <object class="GtkCheckButton" id="x264_bpyramid">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Allows B-Frames to be used as references for other B-Frames. Improves encoding efficiency with little speed penalty</property>
+ <property name="label" translatable="yes">Pyramidal B-Frames</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
+ </object>
+ </child>
<child>
<object class="GtkCheckButton" id="x264_weighted_bframes">
<property name="visible">True</property>
@@ -2825,10 +2845,11 @@
<property name="label" translatable="yes">Weighted B-Frames</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
</object>
<packing>
- <property name="position">2</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
</packing>
</child>
<child>
@@ -2839,10 +2860,11 @@
<property name="tooltip-text" translatable="yes">When B-frame rate distortion optimization is enabled, x264 tries several different methods of compression for each part of a frame, and chooses the one that looks the best. You need to use a subpixel motion estimation refinement level of 6 or 7 for this to work.</property>
<property name="label" translatable="yes">B-Frame Rate Distortion</property>
<property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
</object>
<packing>
- <property name="position">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
</packing>
</child>
<child>
@@ -2854,27 +2876,22 @@
<property name="label" translatable="yes">Bidirectional Refinement</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
</object>
<packing>
- <property name="position">4</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
</packing>
</child>
- <child>
- <object class="GtkCheckButton" id="x264_bpyramid">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Allows B-Frames to be used as references for other B-Frames. Improves encoding efficiency with little speed penalty</property>
- <property name="label" translatable="yes">Pyramidal B-Frames</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+
</object>
<packing>
- <property name="position">5</property>
+ <property name="position">2</property>
</packing>
</child>
+
</object>
</child>
</object>
@@ -2908,14 +2925,20 @@
<property name="left_padding">12</property>
<property name="right_padding">2</property>
<child>
- <object class="GtkEntry" id="x264_options">
+ <object class="GtkTextView" id="x264_options">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Enter x264 options here that are not otherwise available</property>
- <property name="truncate_multiline">True</property>
- <signal handler="generic_entry_changed_cb" name="changed"/>
- <signal handler="generic_focus_out_cb" name="focus_out_event"/>
+ <property name="tooltip-text" translatable="yes">Your selected options will appear here.
+You can edit these and add additional options.
+
+Default values will not be shown. The defaults are:
+ref=1:mixed-refs=0:bframes=0:direct=spatial:b-pyramid=0:
+weightb=0:brdo=0:bime=0:me=hex:merange=16:subme=5:
+analyse=some:8x8dct=0:deblock=0,0:trellis=0:
+no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
+ <property name="wrap_mode">GTK_WRAP_CHAR</property>
+ <property name="accepts_tab">False</property>
+ <signal handler="x264_focus_out_cb" name="focus_out_event"/>
</object>
</child>
</object>
@@ -2930,12 +2953,15 @@
</child>
</object>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="padding">2</property>
<property name="position">2</property>
</packing>
</child>
</object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
</child>
<child>
<object class="GtkVBox" id="vbox25">
@@ -2987,7 +3013,7 @@
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">This sets the shape of the area x264 searches when estimating motion. Your choices are a diamond, a hexagon, a more complex hexagonal shape, or searching the entire frame. You are best off using Uneven Multi-Hexagonal searching.</property>
- <signal handler="setting_widget_changed_cb" name="changed"/>
+ <signal handler="x264_widget_changed_cb" name="changed"/>
</object>
</child>
</object>
@@ -3026,7 +3052,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">This range is the radius, in pixels, x264 should use for motion estimation searches. It only has an effect when you use Uneven Multi-Hexagonal or Exhaustive searching. 24, 32, and 64 are good values.</property>
<property name="adjustment">adjustment10</property>
- <signal handler="setting_widget_changed_cb" name="value_changed"/>
+ <signal handler="x264_widget_changed_cb" name="value_changed"/>
</object>
</child>
</object>
@@ -3066,7 +3092,7 @@
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Determines how motion estimation decisions are made. 1 is lowest quality and fastest. 7 is highest quality and slowest. 5 or 6 are commonly used values.</property>
- <signal handler="setting_widget_changed_cb" name="changed"/>
+ <signal handler="x264_widget_changed_cb" name="changed"/>
</object>
</child>
</object>
@@ -3107,7 +3133,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Determines which macroblock partitions are analyzed.
"Some" is p8x8, b8x8, i8x8, i4x4.</property>
- <signal handler="setting_widget_changed_cb" name="changed"/>
+ <signal handler="x264_widget_changed_cb" name="changed"/>
</object>
</child>
</object>
@@ -3131,7 +3157,7 @@
<property name="label" translatable="yes">8x8dct</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
</object>
</child>
</object>
@@ -3203,7 +3229,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Deblocking filter. Alpha: determines the strength of the deblocking action.</property>
<property name="adjustment">adjustment11</property>
- <signal handler="setting_widget_changed_cb" name="value_changed"/>
+ <signal handler="x264_widget_changed_cb" name="value_changed"/>
</object>
<packing>
<property name="expand">False</property>
@@ -3217,7 +3243,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Deblocking filter. Beta: determines when something is a block. Higher values increase sensitivity and will flag more blocks.</property>
<property name="adjustment">adjustment12</property>
- <signal handler="setting_widget_changed_cb" name="value_changed"/>
+ <signal handler="x264_widget_changed_cb" name="value_changed"/>
</object>
<packing>
<property name="expand">False</property>
@@ -3246,7 +3272,7 @@
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Trellis fine-tunes how bitrate is doled out, so it can reduce file size/bitrate or increase quality. "All" forces it to be used more often than "Final Macro Block".</property>
- <signal handler="setting_widget_changed_cb" name="changed"/>
+ <signal handler="x264_widget_changed_cb" name="changed"/>
</object>
<packing>
<property name="expand">False</property>
@@ -3267,7 +3293,7 @@
<property name="label" translatable="yes">No Fast P-Skip</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
</object>
<packing>
<property name="position">2</property>
@@ -3282,7 +3308,7 @@
<property name="label" translatable="yes">No DCT Decimate</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
</object>
<packing>
<property name="position">3</property>
@@ -3297,7 +3323,7 @@
<property name="label" translatable="yes">CABAC Entropy Encoding</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
+ <signal handler="x264_widget_changed_cb" name="toggled"/>
</object>
<packing>
<property name="position">4</property>
@@ -3323,6 +3349,7 @@
</child>
</object>
<packing>
+ <property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index 95d6b2df8..dd63ccf16 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -188,6 +188,7 @@ static options_map_t d_analyse_opts[] =
{"Some", "some", 0, 0.0, "some"},
{"None", "none", 1, 0.0, "none"},
{"All", "all", 2, 0.0, "all"},
+ {"Custom", "custom", 3, 0.0, "all"},
};
combo_opts_t analyse_opts =
{
@@ -197,9 +198,9 @@ combo_opts_t analyse_opts =
static options_map_t d_trellis_opts[] =
{
- {"Disabled", "off", 0, 0.0, ""},
- {"Final Macro Block", "fmb", 1, 0.0, ""},
- {"Always", "always", 2, 0.0, ""},
+ {"Disabled", "0", 0, 0.0, "0"},
+ {"Final Macro Block", "1", 1, 0.0, "1"},
+ {"Always", "2", 2, 0.0, "2"},
};
combo_opts_t trellis_opts =
{
@@ -1438,113 +1439,16 @@ static const char * turbo_opts =
gchar*
ghb_build_x264opts_string(GHashTable *settings)
{
- GString *x264opts = g_string_new("");
- gint refs = ghb_settings_get_int(settings, "x264_refs");
- if (refs != 1)
- {
- g_string_append_printf(x264opts, "ref=%d:", refs);
- }
- if (refs > 1)
- {
- if (ghb_settings_get_bool(settings, "x264_mixed_refs"))
- {
- g_string_append(x264opts, "mixed-refs=1:");
- }
- }
- gint subme = ghb_settings_get_int(settings, "x264_subme");
- if (subme != 5) // 5 is default
- {
- g_string_append_printf(x264opts, "subme=%d:", subme);
- }
- gint bframes = ghb_settings_get_int(settings, "x264_bframes");
- if (bframes > 0)
- {
- g_string_append_printf(x264opts, "bframes=%d:", bframes);
- if (ghb_settings_get_bool(settings, "x264_weighted_bframes"))
- {
- g_string_append(x264opts, "weightb=1:");
- }
- if (subme >= 6)
- {
- if (ghb_settings_get_bool(settings, "x264_brdo"))
- {
- g_string_append(x264opts, "brdo=1:");
- }
- }
- if (ghb_settings_get_bool(settings, "x264_bime"))
- {
- g_string_append(x264opts, "bime=1:");
- }
- }
- if (bframes > 1)
- {
- if (ghb_settings_get_bool(settings, "x264_bpyramid"))
- {
- g_string_append(x264opts, "b-pyramid=1:");
- }
- }
- if (ghb_settings_get_bool(settings, "x264_no_fast_pskip"))
- {
- g_string_append(x264opts, "no-fast-pskip=1:");
- }
- if (ghb_settings_get_bool(settings, "x264_no_dct_decimate"))
- {
- g_string_append(x264opts, "no-dct-decimate=1:");
- }
- if (!ghb_settings_get_bool(settings, "x264_cabac"))
+ gchar *result;
+ const gchar *opts = ghb_settings_get_string(settings, "x264_options");
+ if (opts != NULL)
{
- g_string_append(x264opts, "cabac=0:");
+ result = g_strdup(opts);
}
else
{
- gint trellis = ghb_settings_get_int(settings, "x264_trellis");
- if (trellis != 0); // != None
- {
- g_string_append_printf(x264opts, "trellis=%d:", trellis);
- }
- }
- gint dba, dbb;
- dba = ghb_settings_get_int(settings, "x264_deblock_alpha");
- dbb = ghb_settings_get_int(settings, "x264_deblock_beta");
- if (dba != 0 || dbb != 0)
- {
- g_string_append_printf(x264opts, "deblock=%d,%d:", dba, dbb);
- }
- const gchar *me = ghb_settings_get_string(settings, "x264_me");
- g_string_append_printf(x264opts, "me=%s:", me);
- gint analyse = ghb_settings_get_int(settings, "x264_analyse");
- if (analyse != 0) // != Some
- {
- g_string_append_printf(x264opts, "analyse=%s:",
- ghb_settings_get_string(settings, "x264_analyse"));
+ result = g_strdup("");
}
- if (ghb_settings_get_bool(settings, "x264_8x8dct"))
- {
- g_string_append(x264opts, "8x8dct:");
- }
- if (analyse != 1) // != none
- {
- gint direct = ghb_settings_get_int(settings, "x264_direct");
- if (direct != 1) // !spatial
- {
- g_string_append_printf(x264opts, "direct=%s:",
- ghb_settings_get_string(settings, "x264_direct"));
- }
- }
- g_string_append_printf(x264opts, "merange=%d:",
- ghb_settings_get_int(settings, "x264_merange"));
-
- const gchar *opts = ghb_settings_get_string(settings, "x264_options");
- if (opts != NULL && opts[0] != 0)
- {
- g_string_append_printf(x264opts, "%s:", opts);
- }
- // 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/internal_defaults b/gtk/src/internal_defaults
index 4206e64c2..0a8d33f59 100644
--- a/gtk/src/internal_defaults
+++ b/gtk/src/internal_defaults
@@ -42,26 +42,7 @@ vquality_type_target=disable
video_bitrate=1800
video_target_size=700
video_quality=64
-x264_direct=spatial
-x264_weighted_bframes=disable
-x264_bime=disable
-x264_merange=16
x264_options=
-x264_cabac=enable
-x264_deblock_beta=0
-x264_analyse=some
-x264_8x8dct=disable
-x264_bframes=0
-x264_no_dct_decimate=disable
-x264_subme=5
-x264_brdo=disable
-x264_bpyramid=disable
-x264_no_fast_pskip=disable
-x264_refs=1
-x264_me=umh
-x264_deblock_alpha=0
-x264_mixed_refs=disable
-x264_trellis=off
directqp=disable
[Initialization]
@@ -74,6 +55,25 @@ crop_top=0
crop_bottom=0
crop_left=0
crop_right=0
+x264_refs=1
+x264_mixed_refs=disable
+x264_bframes=0
+x264_direct=spatial
+x264_weighted_bframes=disable
+x264_brdo=disable
+x264_bime=disable
+x264_bpyramid=disable
+x264_me=hex
+x264_merange=16
+x264_subme=5
+x264_analyse=some
+x264_8x8dct=disable
+x264_deblock_alpha=0
+x264_deblock_beta=0
+x264_trellis=0
+x264_no_fast_pskip=disable
+x264_no_dct_decimate=disable
+x264_cabac=enable
[Preferences]
version=0.1
diff --git a/gtk/src/internal_defaults.h b/gtk/src/internal_defaults.h
index ea62833f7..28c53935f 100644
--- a/gtk/src/internal_defaults.h
+++ b/gtk/src/internal_defaults.h
@@ -42,26 +42,7 @@
"video_bitrate=1800\n"
"video_target_size=700\n"
"video_quality=64\n"
-"x264_direct=spatial\n"
-"x264_weighted_bframes=disable\n"
-"x264_bime=disable\n"
-"x264_merange=16\n"
"x264_options=\n"
-"x264_cabac=enable\n"
-"x264_deblock_beta=0\n"
-"x264_analyse=some\n"
-"x264_8x8dct=disable\n"
-"x264_bframes=0\n"
-"x264_no_dct_decimate=disable\n"
-"x264_subme=5\n"
-"x264_brdo=disable\n"
-"x264_bpyramid=disable\n"
-"x264_no_fast_pskip=disable\n"
-"x264_refs=1\n"
-"x264_me=umh\n"
-"x264_deblock_alpha=0\n"
-"x264_mixed_refs=disable\n"
-"x264_trellis=off\n"
"directqp=disable\n"
"\n"
"[Initialization]\n"
@@ -74,6 +55,25 @@
"crop_bottom=0\n"
"crop_left=0\n"
"crop_right=0\n"
+"x264_refs=1\n"
+"x264_mixed_refs=disable\n"
+"x264_bframes=0\n"
+"x264_direct=spatial\n"
+"x264_weighted_bframes=disable\n"
+"x264_brdo=disable\n"
+"x264_bime=disable\n"
+"x264_bpyramid=disable\n"
+"x264_me=hex\n"
+"x264_merange=16\n"
+"x264_subme=5\n"
+"x264_analyse=some\n"
+"x264_8x8dct=disable\n"
+"x264_deblock_alpha=0\n"
+"x264_deblock_beta=0\n"
+"x264_trellis=0\n"
+"x264_no_fast_pskip=disable\n"
+"x264_no_dct_decimate=disable\n"
+"x264_cabac=enable\n"
"\n"
"[Preferences]\n"
"version=0.1\n"
diff --git a/gtk/src/main.c b/gtk/src/main.c
index 0d5ffadd4..53b71d953 100644
--- a/gtk/src/main.c
+++ b/gtk/src/main.c
@@ -463,6 +463,8 @@ watch_volumes(signal_user_data_t *ud)
extern int mm_flags;
int mm_support();
+void x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud);
+
int
main (int argc, char *argv[])
{
@@ -515,6 +517,15 @@ main (int argc, char *argv[])
ud->builder = create_builder_or_die (BUILDER_NAME, builder_file);
g_free(builder_file);
}
+
+ // Need to connect x264_options textview buffer to the changed signal
+ // since it can't be done automatically
+ GtkTextView *textview;
+ GtkTextBuffer *buffer;
+ textview = GTK_TEXT_VIEW(GHB_WIDGET (ud->builder, "x264_options"));
+ buffer = gtk_text_view_get_buffer (textview);
+ g_signal_connect(buffer, "changed", (GCallback)x264_entry_changed_cb, ud);
+
ghb_file_menu_add_dvd(ud);
ghb_backend_init(ud->builder, 1, 0);
@@ -555,6 +566,8 @@ main (int argc, char *argv[])
if (preset == NULL)
preset = ghb_presets_get_name(0);
}
+ // Parsing x264 options "" initializes x264 widgets to proper defaults
+ ghb_x264_parse_options(ud, "");
ghb_select_preset(ud->builder, preset);
ghb_prefs_to_ui(ud);
// Grey out widgets that are dependent on a disabled feature
diff --git a/gtk/src/settings.c b/gtk/src/settings.c
index 31678de7c..1e78fcbd6 100644
--- a/gtk/src/settings.c
+++ b/gtk/src/settings.c
@@ -311,12 +311,13 @@ ghb_widget_value(GtkWidget *widget)
return NULL;
}
value = g_malloc(sizeof(setting_value_t));
+
+ type = GTK_WIDGET_TYPE(widget);
if (GTK_IS_ACTION(widget))
name = gtk_action_get_name(GTK_ACTION(widget));
else
name = gtk_widget_get_name(widget);
g_debug("ghb_widget_value widget (%s)\n", name);
- type = GTK_OBJECT_TYPE(widget);
if (type == GTK_TYPE_ENTRY)
{
const gchar *str = gtk_entry_get_text((GtkEntry*)widget);
@@ -336,7 +337,7 @@ ghb_widget_value(GtkWidget *widget)
g_debug("\tenable");
value->option = g_strdup("enable");
value->shortOpt = g_strdup("enable");
- value->svalue = g_strdup("enable");
+ value->svalue = g_strdup("1");
value->ivalue = 1;
value->dvalue = 1;
}
@@ -345,7 +346,7 @@ ghb_widget_value(GtkWidget *widget)
g_debug("\tdisable");
value->option = g_strdup("disable");
value->shortOpt = g_strdup("disable");
- value->svalue = g_strdup("disable");
+ value->svalue = g_strdup("0");
value->ivalue = 0;
value->dvalue = 0;
}
@@ -359,7 +360,7 @@ ghb_widget_value(GtkWidget *widget)
g_debug("\tenable");
value->option = g_strdup("enable");
value->shortOpt = g_strdup("enable");
- value->svalue = g_strdup("enable");
+ value->svalue = g_strdup("1");
value->ivalue = 1;
value->dvalue = 1;
}
@@ -368,7 +369,7 @@ ghb_widget_value(GtkWidget *widget)
g_debug("\tdisable");
value->option = g_strdup("disable");
value->shortOpt = g_strdup("disable");
- value->svalue = g_strdup("disable");
+ value->svalue = g_strdup("0");
value->ivalue = 0;
value->dvalue = 0;
}
@@ -382,7 +383,7 @@ ghb_widget_value(GtkWidget *widget)
g_debug("\tenable");
value->option = g_strdup("enable");
value->shortOpt = g_strdup("enable");
- value->svalue = g_strdup("enable");
+ value->svalue = g_strdup("1");
value->ivalue = 1;
value->dvalue = 1;
}
@@ -391,7 +392,7 @@ ghb_widget_value(GtkWidget *widget)
g_debug("\tdisable");
value->option = g_strdup("disable");
value->shortOpt = g_strdup("disable");
- value->svalue = g_strdup("disable");
+ value->svalue = g_strdup("0");
value->ivalue = 0;
value->dvalue = 0;
}
@@ -405,7 +406,7 @@ ghb_widget_value(GtkWidget *widget)
g_debug("\tenable");
value->option = g_strdup("enable");
value->shortOpt = g_strdup("enable");
- value->svalue = g_strdup("enable");
+ value->svalue = g_strdup("1");
value->ivalue = 1;
value->dvalue = 1;
}
@@ -414,7 +415,7 @@ ghb_widget_value(GtkWidget *widget)
g_debug("\tdisable");
value->option = g_strdup("disable");
value->shortOpt = g_strdup("disable");
- value->svalue = g_strdup("disable");
+ value->svalue = g_strdup("0");
value->ivalue = 0;
value->dvalue = 0;
}
@@ -477,7 +478,6 @@ ghb_widget_value(GtkWidget *widget)
value->svalue = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
value->option = g_strdup(value->svalue);
value->shortOpt = g_strdup(value->svalue);
- g_debug("text view (%s)\n", value->svalue);
value->ivalue = 0;
value->dvalue = 0;
value->index = 0;
@@ -627,7 +627,7 @@ update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
GType type;
gchar *value;
- g_debug("update_widget\n");
+ g_debug("update_widget");
// make a dup of setting value because the setting hash gets
// modified and thus the value pointer can become invalid.
if (parm_svalue == NULL)
@@ -638,31 +638,31 @@ update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
{
value = g_strdup(parm_svalue);
}
- g_debug("update widget value (%s)\n", value);
+ g_debug("update widget value (%s)", value);
type = GTK_OBJECT_TYPE(widget);
if (type == GTK_TYPE_ENTRY)
{
- g_debug("entry\n");
+ g_debug("entry");
gtk_entry_set_text((GtkEntry*)widget, value);
}
else if (type == GTK_TYPE_RADIO_BUTTON)
{
- g_debug("radio button\n");
+ g_debug("radio button");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), string_is_true(value));
}
else if (type == GTK_TYPE_CHECK_BUTTON)
{
- g_debug("check button\n");
+ g_debug("check button");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), string_is_true(value));
}
else if (type == GTK_TYPE_TOGGLE_ACTION)
{
- g_debug("toggle action\n");
+ g_debug("toggle action");
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(widget), string_is_true(value));
}
else if (type == GTK_TYPE_CHECK_MENU_ITEM)
{
- g_debug("check menu item\n");
+ g_debug("check menu item");
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), string_is_true(value));
}
else if (type == GTK_TYPE_COMBO_BOX)
@@ -673,6 +673,7 @@ update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
gint ivalue;
gboolean foundit = FALSE;
+ g_debug("combo");
store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
if (gtk_tree_model_get_iter_first (store, &iter))
{
@@ -705,7 +706,7 @@ update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
{
gdouble val;
- g_debug("spin\n");
+ g_debug("spin (%s)", value);
val = g_strtod(value, NULL);
gtk_spin_button_set_value((GtkSpinButton*)widget, val);
}
@@ -713,18 +714,19 @@ update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
{
gdouble val;
- g_debug("hscale\n");
+ g_debug("hscale");
val = g_strtod(value, NULL);
gtk_range_set_value((GtkRange*)widget, val);
}
else if (type == GTK_TYPE_TEXT_VIEW)
{
+ g_debug("textview (%s)", value);
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
gtk_text_buffer_set_text (buffer, value, -1);
}
else
{
- g_debug("Attempt to set unknown widget type\n");
+ g_debug("Attempt to set unknown widget type");
}
g_free(value);
}
@@ -753,7 +755,7 @@ ghb_ui_update_int(signal_user_data_t *ud, const gchar *name, gint ivalue)
{
GObject *object;
- g_debug("ghb_ui_update ()\n");
+ g_debug("ghb_ui_update_int ()\n");
object = GHB_OBJECT(ud->builder, name);
if (object == NULL)
{
@@ -1542,3 +1544,471 @@ ghb_presets_remove(GHashTable *settings, const gchar *name)
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;
+}
+
diff --git a/gtk/src/settings.h b/gtk/src/settings.h
index 1610078a0..44f7f906c 100644
--- a/gtk/src/settings.h
+++ b/gtk/src/settings.h
@@ -125,5 +125,8 @@ void ghb_prefs_to_ui(signal_user_data_t *ud);
void ghb_prefs_save(GHashTable *settings);
void ghb_pref_save(GHashTable *settings, const gchar *key);
void ghb_set_preset_default(GHashTable *settings);
+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);
#endif // _SETTINGS_H_
diff --git a/gtk/src/standard_presets b/gtk/src/standard_presets
index 3d1562495..68e03bd81 100755
--- a/gtk/src/standard_presets
+++ b/gtk/src/standard_presets
@@ -3,18 +3,7 @@ preset_description=HandBrake's settings for the Microsoft Xbox 360.
container=mp4
chapter_markers=disable
video_codec=x264
-x264_refs=2
-x264_mixed_refs=enable
-x264_bframes=3
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_direct=auto
-x264_bpyramid=enable
-x264_me=umh
-x264_subme=5
-x264_analyse=all
-x264_no_fast_pskip=enable
-x264_options=level=40:filter=-2,-1
+x264_options=level=40:ref=2:mixed-refs:bframes=3:bime:weightb:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:no-fast-pskip:filter=-2,-1
vquality_type_bitrate=enable
video_bitrate=2000
video_target_size=700
@@ -41,20 +30,7 @@ preset_description=HandBrake's settings for cartoons, anime, and CGI.
container=mkv
chapter_markers=enable
video_codec=x264
-x264_refs=5
-x264_mixed_refs=enable
-x264_bframes=6
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_direct=auto
-x264_bpyramid=enable
-x264_me=umh
-x264_subme=5
-x264_analyse=all
-x264_8x8dct=enable
-x264_trellis=fmb
-x264_no_fast_pskip=enable
-x264_options=nr=150:filter=2,2
+x264_options=ref=5:mixed-refs:bframes=6:bime:weightb:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2
vquality_type_bitrate=enable
video_bitrate=1000
video_target_size=700
@@ -83,13 +59,7 @@ container=m4v
large_mp4=enable
chapter_markers=enable
video_codec=x264
-x264_refs=1
-x264_bframes=3
-x264_me=umh
-x264_subme=5
-x264_trellis=fmb
-x264_no_fast_pskip=enable
-x264_cabac=disable
+x264_options=bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:cabac=0
vquality_type_bitrate=enable
video_bitrate=2500
video_target_size=700
@@ -117,23 +87,7 @@ preset_description=HandBrake's settings maxed out for slowest encoding and highe
container=mkv
chapter_markers=enable
video_codec=x264
-x264_refs=16
-x264_mixed_refs=enable
-x264_bframes=16
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_brdo=enable
-x264_direct=auto
-x264_bpyramid=enable
-x264_me=esa
-x264_merange=64
-x264_subme=7
-x264_analyse=all
-x264_8x8dct=enable
-x264_trellis=fmb
-x264_no_fast_pskip=enable
-x264_no_dct_decimate=enable
-x264_options=filter=-2,-1
+x264_options=ref=16:mixed-refs:bframes=16:bime:weightb:b-rdo:direct=auto:b-pyramid:me=esa:subme=7:me-range=64:analyse=all:8x8dct:trellis=1:no-fast-pskip:no-dct-decimate:filter=-2,-1
vquality_type_bitrate=enable
video_bitrate=1800
video_target_size=700
@@ -188,20 +142,7 @@ preset_description=HandBrake's preset for people without a lot of money to waste
container=mp4
chapter_markers=enable
video_codec=x264
-x264_refs=3
-x264_mixed_refs=enable
-x264_bframes=16
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_brdo=enable
-x264_bpyramid=enable
-x264_direct=auto
-x264_me=umh
-x264_subme=6
-x264_trellis=fmb
-x264_analyse=all
-x264_8x8dct=enable
-x264_no_fast_pskip=enable
+x264_options=ref=3:mixed-refs:bframes=16:bime:weightb:b-rdo:b-pyramid:direct=auto:me=umh:subme=6:trellis=1:analyse=all:8x8dct:no-fast-pskip
vquality_type_target=enable
video_bitrate=1600
video_target_size=695
@@ -256,18 +197,7 @@ preset_description=HandBrake's preset for consistently excellent quality in one
container=mkv
chapter_markers=enable
video_codec=x264
-x264_refs=3
-x264_mixed_refs=enable
-x264_bframes=3
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_brdo=enable
-x264_bpyramid=enable
-x264_me=umh
-x264_subme=6
-x264_analyse=all
-x264_8x8dct=enable
-x264_options=filter=-2,-1
+x264_options=ref=3:mixed-refs:bframes=3:b-pyramid:b-rdo:bime:weightb:filter=-2,-1:subme=6:trellis=1:analyse=all:8x8dct:me=umh
vquality_type_constant=enable
video_bitrate=2000
video_target_size=700
@@ -294,19 +224,7 @@ preset_description=HandBrake's preset for true high profile x264 quality. A good
container=mkv
chapter_markers=enable
video_codec=x264
-x264_refs=5
-x264_mixed_refs=enable
-x264_bframes=3
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_brdo=enable
-x264_bpyramid=enable
-x264_me=umh
-x264_subme=7
-x264_analyse=all
-x264_8x8dct=enable
-x264_trellis=fmb
-x264_no_fast_pskip=enable
+x264_options=ref=5:mixed-refs:bframes=3:bime:weightb:b-rdo:b-pyramid:me=umh:subme=7:trellis=1:analyse=all:8x8dct:no-fast-pskip
vquality_type_bitrate=enable
video_bitrate=1600
video_target_size=700
@@ -334,20 +252,7 @@ preset_description=HandBrake's preset for feature films.
container=mkv
chapter_markers=enable
video_codec=x264
-x264_refs=3
-x264_mixed_refs=enable
-x264_bframes=6
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_brdo=enable
-x264_direct=auto
-x264_bpyramid=enable
-x264_me=umh
-x264_subme=7
-x264_analyse=all
-x264_8x8dct=enable
-x264_trellis=fmb
-x264_no_fast_pskip=enable
+x264_options=ref=3:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip
vquality_type_bitrate=enable
video_bitrate=1800
video_target_size=700
@@ -376,14 +281,7 @@ container=mp4
ipod_file=enable
chapter_markers=enable
video_codec=x264
-x264_refs=1
-x264_me=umh
-x264_subme=6
-x264_analyse=all
-x264_trellis=fmb
-x264_no_fast_pskip=enable
-x264_cabac=disable
-x264_options=level=30
+x264_options=level=30:cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1
vquality_type_bitrate=enable
video_bitrate=960
video_target_size=700
@@ -412,14 +310,7 @@ container=mp4
ipod_file=enable
chapter_markers=enable
video_codec=x264
-x264_refs=1
-x264_me=umh
-x264_subme=6
-x264_analyse=all
-x264_trellis=fmb
-x264_no_fast_pskip=enable
-x264_cabac=disable
-x264_options=level=30:vbv-maxrate=1500:vbv-bufsize=2000
+x264_options=level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1
vquality_type_bitrate=enable
video_bitrate=1500
video_target_size=700
@@ -448,13 +339,7 @@ container=mp4
ipod_file=enable
chapter_markers=enable
video_codec=x264
-x264_refs=1
-x264_me=umh
-x264_subme=6
-x264_analyse=all
-x264_no_fast_pskip=enable
-x264_cabac=disable
-x264_options=level=30:vbv-maxrate=768:vbv-bufsize=2000
+x264_options=level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1
vquality_type_bitrate=enable
video_bitrate=700
video_target_size=700
@@ -482,10 +367,7 @@ preset_description=HandBrake's normal, default settings.
container=mp4
chapter_markers=enable
video_codec=x264
-x264_refs=2
-x264_bframes=2
-x264_me=umh
-x264_subme=5
+x264_options=ref=2:bframes=2:subme=5:me=umh
vquality_type_bitrate=enable
video_bitrate=1500
video_target_size=700
@@ -511,7 +393,6 @@ subtitles=disable
[PSP]
preset_description=HandBrake's settings for the Sony PlayStation Portable.
container=mp4
-chapter_markers=enable
video_codec=ffmpeg
vquality_type_bitrate=enable
video_bitrate=1024
@@ -541,9 +422,7 @@ preset_description=HandBrake's settings for the Sony PlayStation 3.
container=mp4
chapter_markers=disable
video_codec=x264
-x264_me=umh
-x264_subme=5
-x264_options=level=41
+x264_options=level=41:subme=5:me=umh
vquality_type_bitrate=enable
video_bitrate=2500
video_target_size=700
@@ -570,18 +449,7 @@ preset_description=HandBrake's high quality settings for use with QuickTime. It
container=m4v
chapter_markers=enable
video_codec=x264
-x264_refs=3
-x264_mixed_refs=enable
-x264_bframes=3
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_direct=auto
-x264_bpyramid=enable
-x264_me=umh
-x264_subme=5
-x264_analyse=all
-x264_trellis=fmb
-x264_no_fast_pskip=enable
+x264_options=ref=3:mixed-refs:bframes=3:bime:weightb:direct=auto:me=umh:subme=5:analyse=all:trellis=1:no-fast-pskip
vquality_type_bitrate=enable
video_bitrate=2000
video_target_size=700
@@ -609,21 +477,7 @@ preset_description=HandBrake's settings for video from television.
container=mkv
chapter_markers=enable
video_codec=x264
-x264_refs=3
-x264_mixed_refs=enable
-x264_bframes=6
-x264_bime=enable
-x264_weighted_bframes=enable
-x264_brdo=enable
-x264_direct=auto
-x264_bpyramid=enable
-x264_me=umh
-x264_subme=6
-x264_analyse=all
-x264_8x8dct=enable
-x264_trellis=fmb
-x264_no_fast_pskip=enable
-x264_options=nr=150
+x264_options=ref=3:mixed-refs:bframes=6:bime:weightb:direct=auto:b-pyramid:me=umh:subme=6:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip
vquality_type_bitrate=enable
video_bitrate=1300
video_target_size=700