summaryrefslogtreecommitdiffstats
path: root/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gtk')
-rw-r--r--gtk/configure.ac4
-rw-r--r--gtk/src/Makefile.am33
-rw-r--r--gtk/src/callbacks.c1526
-rw-r--r--gtk/src/callbacks.h8
-rw-r--r--gtk/src/hb-backend.c467
-rw-r--r--gtk/src/hb-backend.h45
-rw-r--r--gtk/src/ini_to_plist.c104
-rw-r--r--gtk/src/internal_defaults.h287
-rw-r--r--gtk/src/internal_defaults.xml197
-rw-r--r--gtk/src/main.c50
-rw-r--r--gtk/src/makedeps.c136
-rw-r--r--gtk/src/plist.c587
-rw-r--r--gtk/src/plist.h14
-rw-r--r--gtk/src/preset_to_string.c35
-rw-r--r--gtk/src/presets.c722
-rw-r--r--gtk/src/presets.h37
-rw-r--r--gtk/src/settings.c1758
-rw-r--r--gtk/src/settings.h112
-rwxr-xr-xgtk/src/standard_presets454
-rw-r--r--gtk/src/standard_presets.h1905
-rw-r--r--gtk/src/standard_presets.xml1300
-rw-r--r--gtk/src/values.c678
-rw-r--r--gtk/src/values.h95
-rw-r--r--gtk/src/widget_deps123
-rw-r--r--gtk/src/widget_deps.h123
-rw-r--r--gtk/src/widget_reverse_deps420
-rw-r--r--gtk/src/widget_reverse_deps.h420
27 files changed, 8338 insertions, 3302 deletions
diff --git a/gtk/configure.ac b/gtk/configure.ac
index baee4531d..40d5560b0 100644
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -66,6 +66,10 @@ AM_PROG_LIBTOOL
+PKG_CHECK_MODULES(GHBTOOLS, [glib-2.0 gobject-2.0])
+AC_SUBST(GHBTOOLS_CFLAGS)
+AC_SUBST(GHBTOOLS_LIBS)
+
PKG_CHECK_MODULES(GHB, [gtk+-2.0 >= 2.8 gio-2.0 hal hal-storage])
AC_SUBST(GHB_CFLAGS)
AC_SUBST(GHB_LIBS)
diff --git a/gtk/src/Makefile.am b/gtk/src/Makefile.am
index a942f16d8..02eca572d 100644
--- a/gtk/src/Makefile.am
+++ b/gtk/src/Makefile.am
@@ -72,6 +72,8 @@ AM_CFLAGS =\
-g
bin_PROGRAMS = ghb
+noinst_PROGRAMS = makewidgetdeps quotestring
+
BUILT_SOURCES = HandBrakeCLI
HandBrakeCLI: $(HB_DIR)/HandBrakeCLI
@@ -86,6 +88,12 @@ ghb_SOURCES = \
main.c \
settings.c \
settings.h \
+ presets.c \
+ presets.h \
+ values.c \
+ values.h \
+ plist.c \
+ plist.h \
hb-backend.c \
hb-backend.h \
renderer_button.h \
@@ -100,6 +108,31 @@ ghb_LDADD = $(GHB_LIBS) $(HB_LIBS)
ghb_DEPENDENCIES = $(HB_DIR)/libhb/libhb.a
+makewidgetdeps_SOURCES = \
+ plist.c \
+ plist.h \
+ values.c \
+ values.h \
+ makedeps.c
+
+makewidgetdeps_LDADD = $(GHBTOOLS_LIBS)
+
+quotestring_SOURCES = preset_to_string.c
+
+widget_deps.h: makewidgetdeps quotestring
+ ./makewidgetdeps
+ ./quotestring widget_deps widget_deps.h
+
+widget_reverse_deps.h: makewidgetdeps quotestring
+ ./makewidgetdeps
+ ./quotestring widget_reverse_deps widget_reverse_deps.h
+
+internal_defaults.h: quotestring internal_defaults.xml
+ ./quotestring internal_defaults.xml internal_defaults.h
+
+standard_presets.h: quotestring standard_presets.xml
+ ./quotestring standard_presets.xml standard_presets.h
+
EXTRA_DIST = $(builder_DATA) $(icons) HandBrakeCLI
uninstall-local:
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c
index 9a68e4715..a0517616b 100644
--- a/gtk/src/callbacks.c
+++ b/gtk/src/callbacks.c
@@ -26,6 +26,9 @@
#include "callbacks.h"
#include "settings.h"
+#include "presets.h"
+#include "values.h"
+#include "plist.h"
#include "hb-backend.h"
#include "ghb-dvd.h"
@@ -34,7 +37,7 @@ static void clear_audio_list(signal_user_data_t *ud);
static GList* dvd_device_list();
static gboolean cancel_encode();
static void audio_list_refresh_selected(signal_user_data_t *ud);
-static GHashTable* get_selected_asettings(signal_user_data_t *ud);
+static GValue* get_selected_asettings(signal_user_data_t *ud);
// This is a dependency map used for greying widgets
// that are dependent on the state of another widget.
@@ -42,138 +45,102 @@ static GHashTable* get_selected_asettings(signal_user_data_t *ud);
// obtained from ghb_widget_value(). For combo boxes
// you will have to look further to combo box options
// maps in hb-backend.c
-typedef struct
-{
- const gchar *widget_name;
- const gchar *dep_name;
- const gchar *enable_value;
- const gboolean disable_if_equal;
-} dependency_t;
-
-static dependency_t dep_map[] =
-{
- {"title", "queue_add", "none", TRUE},
- {"title", "queue_add_menu", "none", TRUE},
- {"title", "preview_button", "none", TRUE},
- {"title", "show_preview_menu", "none", TRUE},
- {"title", "preview_frame", "none", TRUE},
- {"title", "picture_label", "none", TRUE},
- {"title", "picture_tab", "none", TRUE},
- {"title", "chapters_label", "none", TRUE},
- {"title", "chapters_tab", "none", TRUE},
- {"title", "title", "none", TRUE},
- {"title", "start_chapter", "none", TRUE},
- {"title", "end_chapter", "none", TRUE},
- {"vquality_type_bitrate", "video_bitrate", "enable", FALSE},
- {"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", "two_pass", "enable", TRUE},
- {"vquality_type_constant", "turbo", "enable", TRUE},
- {"two_pass", "turbo", "enable", FALSE},
- {"container", "large_mp4", "mp4|m4v", FALSE},
- {"container", "http_optimize_mp4", "mp4|m4v", FALSE},
- {"container", "ipod_file", "mp4|m4v", FALSE},
- {"container", "variable_frame_rate", "avi", TRUE},
- {"variable_frame_rate", "framerate", "enable", TRUE},
- {"variable_frame_rate", "detelecine", "enable", TRUE},
- {"decomb", "deinterlace", "enable", TRUE},
- {"decomb", "tweak_deinterlace", "enable", TRUE},
- {"autocrop", "crop_top", "disable", FALSE},
- {"autocrop", "crop_bottom", "disable", FALSE},
- {"autocrop", "crop_left", "disable", FALSE},
- {"autocrop", "crop_right", "disable", FALSE},
- {"autoscale", "scale_width", "disable", FALSE},
- {"autoscale", "scale_height", "disable", FALSE},
- {"anamorphic", "keep_aspect", "disable", FALSE},
- {"anamorphic", "scale_height", "disable", FALSE},
- {"keep_aspect", "scale_height", "disable", FALSE},
- {"video_codec", "x264_tab", "x264", FALSE},
- {"video_codec", "x264_tab_label", "x264", FALSE},
- {"video_codec", "ipod_file", "x264", FALSE},
- {"audio_codec", "audio_bitrate", "ac3", TRUE},
- {"audio_codec", "audio_rate", "ac3", TRUE},
- {"audio_codec", "audio_mix", "ac3", TRUE},
- {"audio_codec", "audio_drc", "ac3", TRUE},
- {"x264_bframes", "x264_weighted_bframes", "0", TRUE},
- {"x264_bframes", "x264_brdo", "0", TRUE},
- {"x264_bframes", "x264_bime", "0", TRUE},
- {"x264_bframes", "x264_bpyramid", "<2", TRUE},
- {"x264_bframes", "x264_direct", "0", TRUE},
- {"x264_refs", "x264_mixed_refs", "<2", TRUE},
- {"x264_cabac", "x264_trellis", "enable", FALSE},
- {"x264_subme", "x264_brdo", "<6", TRUE},
- {"x264_analyse", "x264_direct", "none", TRUE},
- {"x264_me", "x264_merange", "umh|esa", FALSE},
- {"chapter_markers", "chapters_list", "enable", FALSE},
-};
+
+GValue *dep_map;
+GValue *rev_map;
+
+const gchar widget_deps[] =
+#include "widget_deps.h"
+;
+
+const gchar widget_reverse_deps[] =
+#include "widget_reverse_deps.h"
+;
+
+void
+ghb_init_dep_map()
+{
+ dep_map = ghb_plist_parse(widget_deps, sizeof(widget_deps)-1);
+ rev_map = ghb_plist_parse(widget_reverse_deps,
+ sizeof(widget_reverse_deps)-1);
+}
static gboolean
dep_check(signal_user_data_t *ud, const gchar *name)
{
GtkWidget *widget;
GObject *dep_object;
- int ii;
- int count = sizeof(dep_map) / sizeof(dependency_t);
+ gint ii;
+ gint count;
gboolean result = TRUE;
+ GValue *array, *data;
+ gchar *widget_name;
- g_debug("dep_check () %s\n", name);
+ g_debug("dep_check () %s", name);
+
+ array = ghb_dict_lookup(rev_map, name);
+ count = ghb_array_len(array);
for (ii = 0; ii < count; ii++)
{
- if (strcmp(dep_map[ii].dep_name, name) == 0)
+ data = ghb_array_get_nth(array, ii);
+ widget_name = ghb_value_string(ghb_array_get_nth(data, 0));
+ widget = GHB_WIDGET(ud->builder, widget_name);
+ dep_object = gtk_builder_get_object(ud->builder, name);
+ g_free(widget_name);
+ if (dep_object == NULL)
{
- widget = GHB_WIDGET(ud->builder, dep_map[ii].widget_name);
- dep_object = gtk_builder_get_object(ud->builder, dep_map[ii].dep_name);
- if (dep_object == NULL)
- {
- g_message("Failed to find widget\n");
- }
+ g_message("Failed to find widget");
+ }
+ else
+ {
+ gchar *value;
+ gint jj = 0;
+ gchar **values;
+ gboolean sensitive = FALSE;
+ gboolean die;
+
+ die = ghb_value_boolean(ghb_array_get_nth(data, 2));
+ value = ghb_value_string(ghb_array_get_nth(data, 1));
+ values = g_strsplit(value, "|", 10);
+ g_free(value);
+
+ if (widget)
+ value = ghb_widget_string(widget);
else
+ value = ghb_settings_get_string(ud->settings, name);
+ while (values && values[jj])
{
- 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] == '>')
{
- if (values[jj][0] == '>')
+ gdouble dbl = g_strtod (&values[jj][1], NULL);
+ gdouble dvalue = ghb_widget_double(widget);
+ if (dvalue > dbl)
{
- gdouble dbl = g_strtod (&values[jj][1], NULL);
- gdouble dvalue = ghb_widget_dbl (widget);
- if (dvalue > dbl)
- {
- sensitive = TRUE;
- break;
- }
- }
- else if (values[jj][0] == '<')
- {
- gdouble dbl = g_strtod (&values[jj][1], NULL);
- gdouble dvalue = ghb_widget_dbl (widget);
- if (dvalue < dbl)
- {
- sensitive = TRUE;
- break;
- }
+ sensitive = TRUE;
+ break;
}
- if (strcmp(values[jj], value) == 0)
+ }
+ else if (values[jj][0] == '<')
+ {
+ gdouble dbl = g_strtod (&values[jj][1], NULL);
+ gdouble dvalue = ghb_widget_double(widget);
+ if (dvalue < dbl)
{
sensitive = TRUE;
break;
}
- jj++;
}
- sensitive = dep_map[ii].disable_if_equal ^ sensitive;
- if (!sensitive) result = FALSE;
- g_strfreev (values);
- g_free(value);
+ if (strcmp(values[jj], value) == 0)
+ {
+ sensitive = TRUE;
+ break;
+ }
+ jj++;
}
+ sensitive = die ^ sensitive;
+ if (!sensitive) result = FALSE;
+ g_strfreev (values);
+ g_free(value);
}
}
return result;
@@ -184,51 +151,59 @@ check_depencency(signal_user_data_t *ud, GtkWidget *widget)
{
GObject *dep_object;
const gchar *name;
- int ii;
- int count = sizeof(dep_map) / sizeof(dependency_t);
+ GValue *array, *data;
+ gint count, ii;
+ gchar *dep_name;
if (ghb_widget_index(widget) < 0) return;
+
name = gtk_widget_get_name(widget);
- g_debug("check_depencency () %s\n", name);
+ g_debug("check_depencency () %s", name);
+
+ array = ghb_dict_lookup(dep_map, name);
+ count = ghb_array_len(array);
for (ii = 0; ii < count; ii++)
{
- if (strcmp(dep_map[ii].widget_name, name) == 0)
- {
- gboolean sensitive;
+ gboolean sensitive;
- dep_object = gtk_builder_get_object (ud->builder, dep_map[ii].dep_name);
- if (dep_object == NULL)
- {
- g_message("Failed to find dependent widget %s\n", dep_map[ii].dep_name);
- continue;
- }
- sensitive = dep_check(ud, dep_map[ii].dep_name);
- if (GTK_IS_ACTION(dep_object))
- gtk_action_set_sensitive(GTK_ACTION(dep_object), sensitive);
- else
- gtk_widget_set_sensitive(GTK_WIDGET(dep_object), sensitive);
+ data = ghb_array_get_nth(array, ii);
+ dep_name = ghb_value_string(data);
+ dep_object = gtk_builder_get_object(ud->builder, dep_name);
+ if (dep_object == NULL)
+ {
+ g_message("Failed to find dependent widget %s", dep_name);
+ g_free(dep_name);
+ continue;
}
+ sensitive = dep_check(ud, dep_name);
+ g_free(dep_name);
+ if (GTK_IS_ACTION(dep_object))
+ gtk_action_set_sensitive(GTK_ACTION(dep_object), sensitive);
+ else
+ gtk_widget_set_sensitive(GTK_WIDGET(dep_object), sensitive);
}
}
void
ghb_check_all_depencencies(signal_user_data_t *ud)
{
+ GHashTableIter iter;
+ gchar *dep_name;
+ GValue *value;
GObject *dep_object;
- int ii;
- int count = sizeof(dep_map) / sizeof(dependency_t);
- g_debug("ghb_check_all_depencencies ()\n");
- for (ii = 0; ii < count; ii++)
+ g_debug("ghb_check_all_depencencies ()");
+ ghb_dict_iter_init(&iter, rev_map);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&dep_name, (gpointer*)&value))
{
gboolean sensitive;
- dep_object = gtk_builder_get_object (ud->builder, dep_map[ii].dep_name);
+ dep_object = gtk_builder_get_object (ud->builder, dep_name);
if (dep_object == NULL)
{
- g_message("Failed to find dependent widget %s\n", dep_map[ii].dep_name);
+ g_message("Failed to find dependent widget %s", dep_name);
continue;
}
- sensitive = dep_check(ud, dep_map[ii].dep_name);
+ sensitive = dep_check(ud, dep_name);
if (GTK_IS_ACTION(dep_object))
gtk_action_set_sensitive(GTK_ACTION(dep_object), sensitive);
else
@@ -243,7 +218,7 @@ clear_presets_selection(signal_user_data_t *ud)
GtkTreeSelection *selection;
if (ud->dont_clear_presets) return;
- g_debug("clear_presets_selection()\n");
+ g_debug("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);
@@ -257,7 +232,7 @@ expand_tilde(const gchar *path)
const gchar *suffix;
gchar *expanded_path = NULL;
- g_debug("expand_tilde ()\n");
+ g_debug("expand_tilde ()");
if (path[0] == '~')
{
user_home = g_get_home_dir();
@@ -287,7 +262,7 @@ void
on_quit1_activate(GtkMenuItem *quit, signal_user_data_t *ud)
{
gint state = ghb_get_state();
- g_debug("on_quit1_activate ()\n");
+ g_debug("on_quit1_activate ()");
if (state & GHB_STATE_WORKING)
{
if (cancel_encode("Closing HandBrake will terminate encoding.\n"))
@@ -305,22 +280,21 @@ on_quit1_activate(GtkMenuItem *quit, signal_user_data_t *ud)
static void
set_destination(signal_user_data_t *ud)
{
- if (ghb_settings_get_bool(ud->settings, "use_source_name"))
+ g_debug("set_destination");
+ if (ghb_settings_get_boolean(ud->settings, "use_source_name"))
{
- const gchar *vol_name, *filename, *extension;
+ gchar *vol_name, *filename, *extension;
gchar *dir, *new_name;
filename = ghb_settings_get_string(ud->settings, "destination");
extension = ghb_settings_get_string(ud->settings, "container");
dir = g_path_get_dirname (filename);
vol_name = ghb_settings_get_string(ud->settings, "volume_label");
- g_debug("volume_label (%s)\n", vol_name);
- if (vol_name == NULL)
- {
- vol_name = "new_video";
- }
new_name = g_strdup_printf("%s/%s.%s", dir, vol_name, extension);
- ghb_ui_update(ud, "destination", new_name);
+ ghb_ui_update(ud, "destination", ghb_string_value(new_name));
+ g_free(filename);
+ g_free(extension);
+ g_free(vol_name);
g_free(dir);
g_free(new_name);
}
@@ -496,7 +470,7 @@ source_type_changed_cb(GtkToggleButton *toggle, GtkFileChooser *chooser)
{
gchar *filename;
- g_debug("source_type_changed_cb ()\n");
+ g_debug("source_type_changed_cb ()");
if (gtk_toggle_button_get_active (toggle))
{
filename = gtk_file_chooser_get_filename (chooser);
@@ -582,12 +556,13 @@ do_scan(signal_user_data_t *ud, const gchar *filename)
{
GtkProgressBar *progress;
progress = GTK_PROGRESS_BAR(GHB_WIDGET(ud->builder, "progressbar"));
- const gchar *path;
+ gchar *path;
path = ghb_settings_get_string( ud->settings, "source");
gtk_progress_bar_set_fraction (progress, 0);
gtk_progress_bar_set_text (progress, "Scanning ...");
ghb_hb_cleanup(TRUE);
ghb_backend_scan (path, 0);
+ g_free(path);
}
else
{
@@ -601,12 +576,12 @@ source_button_clicked_cb(GtkButton *button, signal_user_data_t *ud)
{
GtkWidget *dialog;
GtkWidget *widget;
- const gchar *sourcename;
+ gchar *sourcename;
gint response;
GtkFileChooserAction action;
gboolean checkbutton_active;
- g_debug("source_browse_clicked_cb ()\n");
+ g_debug("source_browse_clicked_cb ()");
sourcename = ghb_settings_get_string(ud->settings, "source");
checkbutton_active = FALSE;
if (g_file_test(sourcename, G_FILE_TEST_IS_DIR))
@@ -646,6 +621,7 @@ source_button_clicked_cb(GtkButton *button, signal_user_data_t *ud)
g_free(filename);
}
}
+ g_free(sourcename);
gtk_widget_destroy(dialog);
}
@@ -653,7 +629,7 @@ void
dvd_source_activate_cb(GtkAction *action, signal_user_data_t *ud)
{
const gchar *filename;
- const gchar *sourcename;
+ gchar *sourcename;
sourcename = ghb_settings_get_string(ud->settings, "source");
filename = gtk_action_get_name(action);
@@ -664,6 +640,7 @@ dvd_source_activate_cb(GtkAction *action, signal_user_data_t *ud)
ghb_pref_save (ud->settings, "default_source");
ghb_dvd_set_current (filename, ud);
}
+ g_free(sourcename);
}
static void
@@ -671,11 +648,11 @@ update_destination_extension(signal_user_data_t *ud)
{
static gchar *containers[] = {".mkv", ".mp4", ".m4v", ".avi", ".ogm", NULL};
gchar *filename;
- const gchar *extension;
+ gchar *extension;
gint ii;
GtkEntry *entry;
- g_debug("update_destination_extension ()\n");
+ g_debug("update_destination_extension ()");
extension = ghb_settings_get_string(ud->settings, "container");
entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "destination"));
filename = g_strdup(gtk_entry_get_text(entry));
@@ -699,11 +676,12 @@ update_destination_extension(signal_user_data_t *ud)
break;
}
new_name = g_strjoin(".", filename, extension, NULL);
- ghb_ui_update(ud, "destination", new_name);
+ ghb_ui_update(ud, "destination", ghb_string_value(new_name));
g_free(new_name);
break;
}
}
+ g_free(extension);
g_free(filename);
}
@@ -714,7 +692,7 @@ destination_entry_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
{
gchar *dest;
- g_debug("destination_entry_changed_cb ()\n");
+ g_debug("destination_entry_changed_cb ()");
if ((dest = expand_tilde(gtk_entry_get_text(entry))) != NULL)
{
gtk_entry_set_text(entry, dest);
@@ -732,10 +710,10 @@ destination_browse_clicked_cb(GtkButton *button, signal_user_data_t *ud)
{
GtkWidget *dialog;
GtkEntry *entry;
- const char *destname;
+ gchar *destname;
gchar *basename;
- g_debug("destination_browse_clicked_cb ()\n");
+ g_debug("destination_browse_clicked_cb ()");
destname = ghb_settings_get_string(ud->settings, "destination");
dialog = gtk_file_chooser_dialog_new ("Choose Destination",
NULL,
@@ -745,6 +723,7 @@ destination_browse_clicked_cb(GtkButton *button, signal_user_data_t *ud)
NULL);
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), destname);
basename = g_path_get_basename(destname);
+ g_free(destname);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), basename);
g_free(basename);
if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
@@ -755,7 +734,7 @@ destination_browse_clicked_cb(GtkButton *button, signal_user_data_t *ud)
entry = (GtkEntry*)GHB_WIDGET(ud->builder, "destination");
if (entry == NULL)
{
- g_debug("Failed to find widget: %s\n", "destination");
+ g_debug("Failed to find widget: %s", "destination");
}
else
{
@@ -769,7 +748,7 @@ destination_browse_clicked_cb(GtkButton *button, signal_user_data_t *ud)
gboolean
window_destroy_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *ud)
{
- g_debug("window_destroy_event_cb ()\n");
+ g_debug("window_destroy_event_cb ()");
ghb_hb_cleanup(FALSE);
gtk_main_quit();
return FALSE;
@@ -779,7 +758,7 @@ gboolean
window_delete_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *ud)
{
gint state = ghb_get_state();
- g_debug("window_delete_event_cb ()\n");
+ g_debug("window_delete_event_cb ()");
if (state & GHB_STATE_WORKING)
{
if (cancel_encode("Closing HandBrake will terminate encoding.\n"))
@@ -804,21 +783,25 @@ update_acodec_combo(signal_user_data_t *ud)
void
container_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("container_changed_cb ()\n");
+ const GValue *audio_list;
+ g_debug("container_changed_cb ()");
ghb_widget_to_setting(ud->settings, widget);
update_destination_extension(ud);
check_depencency(ud, widget);
update_acodec_combo(ud);
clear_presets_selection(ud);
- if (ghb_ac3_in_audio_list (ud->audio_settings))
+
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (ghb_ac3_in_audio_list (audio_list))
{
- const gchar *container;
+ gchar *container;
container = ghb_settings_get_string(ud->settings, "container");
if (strcmp(container, "mp4") == 0)
{
- ghb_ui_update(ud, "container", "m4v");
+ ghb_ui_update(ud, "container", ghb_string_value("m4v"));
}
+ g_free(container);
}
}
@@ -880,12 +863,17 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
gtk_label_set_text (GTK_LABEL(widget), text);
g_free(text);
- ghb_ui_update_int (ud, "scale_width", tinfo->width - tinfo->crop[2] - tinfo->crop[3]);
+ ghb_ui_update(ud, "scale_width",
+ ghb_int64_value(tinfo->width - tinfo->crop[2] - tinfo->crop[3]));
// If anamorphic or keep_aspect, the hight will be automatically calculated
- gboolean keep_aspect = ghb_settings_get_bool(ud->settings, "keep_aspect");
- gboolean anamorphic = ghb_settings_get_bool(ud->settings, "anamorphic");
+ gboolean keep_aspect, anamorphic;
+ keep_aspect = ghb_settings_get_boolean(ud->settings, "keep_aspect");
+ anamorphic = ghb_settings_get_boolean(ud->settings, "anamorphic");
if (!(keep_aspect || anamorphic))
- ghb_ui_update_int (ud, "scale_height", tinfo->height - tinfo->crop[0] - tinfo->crop[1]);
+ {
+ ghb_ui_update(ud, "scale_height",
+ ghb_int64_value(tinfo->height - tinfo->crop[0] - tinfo->crop[1]));
+ }
// Set the limits of cropping. hb_set_anamorphic_size crashes if
// you pass it a cropped width or height == 0.
@@ -900,14 +888,14 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
widget = GHB_WIDGET (ud->builder, "crop_right");
gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
- if (ghb_settings_get_bool (ud->settings, "autocrop"))
+ if (ghb_settings_get_boolean(ud->settings, "autocrop"))
{
- ghb_ui_update_int (ud, "crop_top", tinfo->crop[0]);
- ghb_ui_update_int (ud, "crop_bottom", tinfo->crop[1]);
- ghb_ui_update_int (ud, "crop_left", tinfo->crop[2]);
- ghb_ui_update_int (ud, "crop_right", tinfo->crop[3]);
+ ghb_ui_update(ud, "crop_top", ghb_int64_value(tinfo->crop[0]));
+ ghb_ui_update(ud, "crop_bottom", ghb_int64_value(tinfo->crop[1]));
+ ghb_ui_update(ud, "crop_left", ghb_int64_value(tinfo->crop[2]));
+ ghb_ui_update(ud, "crop_right", ghb_int64_value(tinfo->crop[3]));
}
- g_debug("setting max end chapter %d\n", tinfo->num_chapters);
+ g_debug("setting max end chapter %d", tinfo->num_chapters);
widget = GHB_WIDGET (ud->builder, "end_chapter");
gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo->num_chapters);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), tinfo->num_chapters);
@@ -922,8 +910,8 @@ adjust_audio_rate_combos(signal_user_data_t *ud)
ghb_audio_info_t ainfo;
GtkWidget *widget;
- g_debug("adjust_audio_rate_combos ()\n");
- titleindex = ghb_settings_get_index(ud->settings, "title");
+ g_debug("adjust_audio_rate_combos ()");
+ titleindex = ghb_settings_get_combo_index(ud->settings, "title");
widget = GHB_WIDGET(ud->builder, "audio_track");
audioindex = ghb_widget_int(widget);
@@ -931,13 +919,21 @@ adjust_audio_rate_combos(signal_user_data_t *ud)
widget = GHB_WIDGET(ud->builder, "audio_codec");
acodec = ghb_widget_int(widget);
- if (ghb_get_audio_info (&ainfo, titleindex, audioindex) && ghb_audio_is_passthru (acodec))
+ if (ghb_audio_is_passthru (acodec))
{
- // Set the values for bitrate and samplerate to the input rates
- ghb_set_passthru_rate_opts (ud->builder, ainfo.bitrate);
- ghb_ui_update_int (ud, "audio_bitrate", ainfo.bitrate);
- ghb_ui_update_int (ud, "audio_rate", 0);
- ghb_ui_update_int (ud, "audio_mix", 0);
+ if (ghb_get_audio_info (&ainfo, titleindex, audioindex))
+ {
+ // Set the values for bitrate and samplerate to the input rates
+ ghb_set_passthru_rate_opts (ud->builder, ainfo.bitrate);
+ ghb_ui_update(ud, "audio_bitrate", ghb_int64_value(ainfo.bitrate));
+ ghb_ui_update(ud, "audio_rate", ghb_int64_value(0));
+ ghb_ui_update(ud, "audio_mix", ghb_int64_value(0));
+ }
+ else
+ {
+ ghb_ui_update(ud, "audio_rate", ghb_int64_value(0));
+ ghb_ui_update(ud, "audio_mix", ghb_int64_value(0));
+ }
}
else
{
@@ -948,78 +944,93 @@ adjust_audio_rate_combos(signal_user_data_t *ud)
static void
set_pref_audio(gint titleindex, signal_user_data_t *ud)
{
- gint acodec, track, ivalue;
- const gchar *svalue;
+ gint acodec_code, mix_code, track;
+ gchar *source_lang;
GtkWidget *button;
ghb_audio_info_t ainfo;
- gchar* drcstr;
gint index;
GHashTable *track_indicies;
gint *iptr;
+
+ GValue *pref_audio;
+ GValue *audio, *acodec, *bitrate, *rate, *mix, *drc;
+ gint count, ii, list_count;
+ g_debug("set_pref_audio");
track_indicies = g_hash_table_new(g_int_hash, g_int_equal);
// Clear the audio list
clear_audio_list(ud);
// Find "best" audio based on audio preferences
button = GHB_WIDGET (ud->builder, "audio_add");
- svalue = ghb_settings_get_short_opt(ud->settings, "source_audio_lang");
- gint acount = ghb_pref_acount();
- gint ii;
- gint list_count = 0;
- for (ii = 0; ii < acount; ii++)
+ source_lang = ghb_settings_get_string(ud->settings, "source_audio_lang");
+
+ pref_audio = ghb_settings_get_value(ud->settings, "pref_audio_list");
+
+ list_count = 0;
+ count = ghb_array_len(pref_audio);
+ for (ii = 0; ii < count; ii++)
{
- acodec = ghb_pref_acodec(ii);
- iptr = g_hash_table_lookup(track_indicies, &acodec);
+ audio = ghb_array_get_nth(pref_audio, ii);
+ acodec = ghb_settings_get_value(audio, "audio_codec");
+ bitrate = ghb_settings_get_value(audio, "audio_bitrate");
+ rate = ghb_settings_get_value(audio, "audio_rate");
+ mix = ghb_settings_get_value(audio, "audio_mix");
+ drc = ghb_settings_get_value(audio, "audio_drc");
+ acodec_code = ghb_lookup_acodec(acodec);
+ // If there are multiple audios using the same codec, then
+ // select sequential tracks for each. This hash keeps track
+ // of the last used track for each codec.
+ iptr = g_hash_table_lookup(track_indicies, &acodec_code);
if (iptr == NULL)
index = 0;
else
index = *(gint*)iptr;
- track = ghb_find_audio_track(titleindex, svalue, index);
+ track = ghb_find_audio_track(titleindex, source_lang, index);
// Check to see if:
// 1. pref codec is ac3
// 2. source codec is not ac3
// 3. next pref is enabled
if (ghb_get_audio_info (&ainfo, titleindex, track) &&
- ghb_audio_is_passthru (acodec))
+ ghb_audio_is_passthru (acodec_code))
{
if (!ghb_audio_is_passthru(ainfo.codec))
{
- acodec = ghb_get_default_acodec();
- if ((ii + 1 < acount) || (list_count != 0))
+ acodec_code = ghb_get_default_acodec();
+ // If there's more audio to process, or we've already
+ // placed one in the list, then we can skip this one
+ if ((ii + 1 < count) || (list_count != 0))
{
// Skip this audio
- acodec = 0;
+ acodec_code = 0;
}
}
}
if (titleindex >= 0 && track < 0)
- acodec = 0;
- if (acodec != 0)
+ acodec_code = 0;
+ if (acodec_code != 0)
{
// Add to audio list
g_signal_emit_by_name(button, "clicked", ud);
list_count++;
- ghb_ui_update_int(ud, "audio_track", track);
- ghb_ui_update_int(ud, "audio_codec", acodec);
- if (!ghb_audio_is_passthru (acodec))
+ ghb_ui_update(ud, "audio_track", ghb_int64_value(track));
+ ghb_ui_update(ud, "audio_codec", acodec);
+ if (!ghb_audio_is_passthru (acodec_code))
{
// This gets set autimatically if the codec is passthru
- ivalue = ghb_pref_bitrate(ii);
- ghb_ui_update_int(ud, "audio_bitrate", ivalue);
- ivalue = ghb_pref_rate(ii);
- ghb_ui_update_int(ud, "audio_rate", ivalue);
- ivalue = ghb_pref_mix(ii);
- ivalue = ghb_get_best_mix(titleindex, track, acodec, ivalue);
- ghb_ui_update_int(ud, "audio_mix", ivalue);
+ ghb_ui_update(ud, "audio_bitrate", bitrate);
+ ghb_ui_update(ud, "audio_rate", rate);
+ mix_code = ghb_lookup_mix(mix);
+ mix_code = ghb_get_best_mix(
+ titleindex, track, acodec_code, mix_code);
+ ghb_ui_update(ud, "audio_mix", ghb_int64_value(mix_code));
}
- drcstr = g_strdup_printf("%.2g", ghb_pref_drc(ii));
- ghb_ui_update(ud, "audio_drc", drcstr);
- g_free(drcstr);
+ ghb_ui_update(ud, "audio_drc", drc);
index++;
- g_hash_table_insert(track_indicies, &acodec, &index);
+ g_hash_table_insert(track_indicies, &acodec_code, &index);
}
}
+ g_free(source_lang);
g_hash_table_destroy(track_indicies);
}
@@ -1033,7 +1044,7 @@ set_preview_image(signal_user_data_t *ud)
GtkWidget *widget;
gint preview_width, preview_height, target_height, width, height;
- g_debug("set_preview_button_image ()\n");
+ g_debug("set_preview_button_image ()");
gint titleindex = ghb_settings_get_int(ud->settings, "title");
if (titleindex < 0) return;
widget = GHB_WIDGET (ud->builder, "preview_frame");
@@ -1050,7 +1061,7 @@ set_preview_image(signal_user_data_t *ud)
gtk_label_set_text(GTK_LABEL(widget), text);
g_free(text);
- g_debug("preview %d x %d\n", preview_width, preview_height);
+ g_debug("preview %d x %d", preview_width, preview_height);
target_height = MIN(preview_button_height - 12, 128);
height = target_height;
width = preview_width * height / preview_height;
@@ -1075,9 +1086,9 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
ghb_title_info_t tinfo;
gint titleindex;
- const gchar *preset;
+ gchar *preset;
- g_debug("title_changed_cb ()\n");
+ g_debug("title_changed_cb ()");
ghb_widget_to_setting(ud->settings, widget);
check_depencency(ud, widget);
@@ -1086,6 +1097,7 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_update_ui_combo_box (ud->builder, "subtitle_lang", titleindex, FALSE);
preset = ghb_settings_get_string (ud->settings, "preset");
ghb_update_from_preset(ud, preset, "subtitle_lang");
+ g_free(preset);
if (ghb_get_title_info (&tinfo, titleindex))
{
show_title_info(ud, &tinfo);
@@ -1093,17 +1105,17 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
update_chapter_list (ud);
adjust_audio_rate_combos(ud);
set_pref_audio(titleindex, ud);
- if (ghb_settings_get_bool (ud->settings, "vquality_type_target"))
+ if (ghb_settings_get_boolean(ud->settings, "vquality_type_target"))
{
gint bitrate = ghb_calculate_target_bitrate (ud->settings, titleindex);
- ghb_ui_update_int (ud, "video_bitrate", bitrate);
+ ghb_ui_update(ud, "video_bitrate", ghb_int64_value(bitrate));
}
// Unfortunately, there is no way to query how many frames were
// actually generated during the scan. It attempts to make 10.
// If I knew how many were generated, I would adjust the spin
// control range here.
- ghb_ui_update_int (ud, "preview_frame", 1);
+ ghb_ui_update(ud, "preview_frame", ghb_int64_value(1));
set_preview_image (ud);
}
@@ -1112,58 +1124,69 @@ void
audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
static gint prev_acodec = 0;
- gint acodec, ivalue;
- GHashTable *asettings;
+ gint acodec_code, mix_code;
+ GValue *asettings;
+ GValue *pref_audio;
+ GValue *audio, *acodec, *bitrate, *rate, *mix, *drc;
- g_debug("audio_codec_changed_cb ()\n");
-
- acodec = ghb_widget_int(widget);
- if (ghb_audio_is_passthru (prev_acodec) && !ghb_audio_is_passthru (acodec))
+ g_debug("audio_codec_changed_cb ()");
+ acodec_code = ghb_widget_int(widget);
+ if (ghb_audio_is_passthru (prev_acodec) &&
+ !ghb_audio_is_passthru (acodec_code))
{
// Transition from passthru to not, put some audio settings back to
// pref settings
gint titleindex = ghb_settings_get_int(ud->settings, "title");
gint track = ghb_settings_get_int(ud->settings, "audio_track");
- ivalue = ghb_pref_bitrate(0);
- ghb_ui_update_int (ud, "audio_bitrate", ivalue);
- ivalue = ghb_pref_rate(0);
- ghb_ui_update_int (ud, "audio_rate", ivalue);
- ivalue = ghb_pref_mix(0);
- ivalue = ghb_get_best_mix(titleindex, track, acodec, ivalue);
- ghb_ui_update_int (ud, "audio_mix", ivalue);
+ pref_audio = ghb_settings_get_value(ud->settings, "pref_audio_list");
+ audio = ghb_array_get_nth(pref_audio, 0);
+ acodec = ghb_settings_get_value(audio, "audio_codec");
+ bitrate = ghb_settings_get_value(audio, "audio_bitrate");
+ rate = ghb_settings_get_value(audio, "audio_rate");
+ mix = ghb_settings_get_value(audio, "audio_mix");
+ drc = ghb_settings_get_value(audio, "audio_drc");
+
+ ghb_ui_update(ud, "audio_bitrate", bitrate);
+ ghb_ui_update(ud, "audio_rate", rate);
+ mix_code = ghb_lookup_mix(mix);
+ mix_code = ghb_get_best_mix( titleindex, track, acodec_code, mix_code);
+ ghb_ui_update(ud, "audio_mix", ghb_int64_value(mix_code));
}
adjust_audio_rate_combos(ud);
ghb_grey_combo_options (ud->builder);
check_depencency(ud, widget);
- prev_acodec = acodec;
+ prev_acodec = acodec_code;
asettings = get_selected_asettings(ud);
if (asettings != NULL)
{
ghb_widget_to_setting(asettings, widget);
audio_list_refresh_selected(ud);
}
- if (ghb_ac3_in_audio_list (ud->audio_settings))
+
+ const GValue *audio_list;
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (ghb_ac3_in_audio_list (audio_list))
{
- const gchar *container;
+ gchar *container;
container = ghb_settings_get_string(ud->settings, "container");
if (strcmp(container, "mp4") == 0)
{
- ghb_ui_update(ud, "container", "m4v");
+ ghb_ui_update(ud, "container", ghb_string_value("m4v"));
}
+ g_free(container);
}
}
static void audio_list_refresh_selected(signal_user_data_t *ud);
-static GHashTable* get_selected_asettings(signal_user_data_t *ud);
void
audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- GHashTable *asettings;
+ GValue *asettings;
- g_debug("audio_track_changed_cb ()\n");
+ g_debug("audio_track_changed_cb ()");
adjust_audio_rate_combos(ud);
check_depencency(ud, widget);
ghb_grey_combo_options(ud->builder);
@@ -1178,9 +1201,9 @@ audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
void
audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- GHashTable *asettings;
+ GValue *asettings;
- g_debug("audio_widget_changed_cb ()\n");
+ g_debug("audio_widget_changed_cb ()");
check_depencency(ud, widget);
asettings = get_selected_asettings(ud);
if (asettings != NULL)
@@ -1193,7 +1216,7 @@ audio_widget_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 ()\n");
+ g_debug("generic_widget_changed_cb ()");
check_depencency(ud, widget);
}
@@ -1215,7 +1238,7 @@ validate_filter_widget(signal_user_data_t *ud, const gchar *name)
GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, name));
if (ghb_widget_index(GTK_WIDGET(combo)) < 0)
{ // Validate user input
- const gchar *val = ghb_settings_get_string(ud->settings, name);
+ gchar *val = ghb_settings_get_string(ud->settings, name);
store = gtk_combo_box_get_model(combo);
// Check to see if user manually entered one of the combo options
if (gtk_tree_model_get_iter_first(store, &iter))
@@ -1236,6 +1259,7 @@ validate_filter_widget(signal_user_data_t *ud, const gchar *name)
if (!ghb_validate_filter_string(val, -1))
gtk_combo_box_set_active(combo, 0);
}
+ g_free(val);
}
}
@@ -1243,7 +1267,7 @@ gboolean
deint_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
signal_user_data_t *ud)
{
- g_debug("deint_tweak_focus_out_cb ()\n");
+ g_debug("deint_tweak_focus_out_cb ()");
validate_filter_widget(ud, "tweak_deinterlace");
return FALSE;
}
@@ -1252,7 +1276,7 @@ gboolean
denoise_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
signal_user_data_t *ud)
{
- g_debug("denoise_tweak_focus_out_cb ()\n");
+ g_debug("denoise_tweak_focus_out_cb ()");
validate_filter_widget(ud, "tweak_noise");
return FALSE;
}
@@ -1283,32 +1307,16 @@ void
vfr_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
//const gchar *name = gtk_widget_get_name(widget);
- //g_debug("setting_widget_changed_cb () %s\n", name);
+ //g_debug("setting_widget_changed_cb () %s", name);
ghb_widget_to_setting(ud->settings, widget);
check_depencency(ud, widget);
clear_presets_selection(ud);
- if (ghb_settings_get_bool(ud->settings, "variable_frame_rate"))
+ if (ghb_settings_get_boolean(ud->settings, "variable_frame_rate"))
{
- ghb_ui_update_int(ud, "framerate", 0);
+ ghb_ui_update(ud, "framerate", ghb_int64_value(0));
}
}
-void
-mirror_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
- const gchar *name = gtk_widget_get_name(widget);
- if (name == NULL) return;
-
- g_debug("mirror_cb () %s\n", name);
- gchar *mirror = g_strdup(name);
- gchar *pos = g_strrstr(mirror, "_mirror");
- if (pos == NULL) return;
- *pos = 0;
- gchar *value = ghb_widget_short_opt (widget);
- ghb_ui_update (ud, mirror, value);
- g_free(mirror);
-}
-
// subtitles have their differ from other settings in that
// the selection is updated automaitcally when the title
// changes. I don't want the preset selection changed as
@@ -1317,7 +1325,7 @@ void
subtitle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
const gchar *name = gtk_widget_get_name(widget);
- g_debug("subtitle_changed_cb () %s\n", name);
+ g_debug("subtitle_changed_cb () %s", name);
ghb_widget_to_setting(ud->settings, widget);
check_depencency(ud, widget);
}
@@ -1326,15 +1334,15 @@ void
target_size_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
const gchar *name = gtk_widget_get_name(widget);
- g_debug("setting_widget_changed_cb () %s\n", name);
+ g_debug("setting_widget_changed_cb () %s", name);
ghb_widget_to_setting(ud->settings, widget);
check_depencency(ud, widget);
clear_presets_selection(ud);
- if (ghb_settings_get_bool (ud->settings, "vquality_type_target"))
+ if (ghb_settings_get_boolean(ud->settings, "vquality_type_target"))
{
gint titleindex = ghb_settings_get_int(ud->settings, "title");
gint bitrate = ghb_calculate_target_bitrate (ud->settings, titleindex);
- ghb_ui_update_int (ud, "video_bitrate", bitrate);
+ ghb_ui_update(ud, "video_bitrate", ghb_int64_value(bitrate));
}
}
@@ -1342,7 +1350,7 @@ void
start_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
const gchar *name = gtk_widget_get_name(widget);
- g_debug("start_chapter_changed_cb () %s\n", name);
+ g_debug("start_chapter_changed_cb () %s", name);
ghb_widget_to_setting(ud->settings, widget);
GtkWidget *end_ch = GHB_WIDGET (ud->builder, "end_chapter");
gdouble start, end;
@@ -1356,7 +1364,7 @@ void
end_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
const gchar *name = gtk_widget_get_name(widget);
- g_debug("end_chapter_changed_cb () %s\n", name);
+ g_debug("end_chapter_changed_cb () %s", name);
ghb_widget_to_setting(ud->settings, widget);
GtkWidget *start_ch = GHB_WIDGET (ud->builder, "start_chapter");
gdouble start, end;
@@ -1369,7 +1377,7 @@ end_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
void
scale_width_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("scale_width_changed_cb ()\n");
+ g_debug("scale_width_changed_cb ()");
ghb_widget_to_setting(ud->settings, widget);
check_depencency(ud, widget);
ghb_set_scale (ud, GHB_SCALE_KEEP_WIDTH);
@@ -1386,7 +1394,7 @@ scale_width_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
void
scale_height_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("scale_height_changed_cb ()\n");
+ g_debug("scale_height_changed_cb ()");
ghb_widget_to_setting(ud->settings, widget);
check_depencency(ud, widget);
ghb_set_scale (ud, GHB_SCALE_KEEP_HEIGHT);
@@ -1406,7 +1414,7 @@ crop_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
gint titleindex, crop[4];
ghb_title_info_t tinfo;
- g_debug("crop_changed_cb ()\n");
+ g_debug("crop_changed_cb ()");
ghb_widget_to_setting(ud->settings, widget);
check_depencency(ud, widget);
ghb_set_scale (ud, GHB_SCALE_KEEP_NONE);
@@ -1415,7 +1423,7 @@ crop_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
crop[1] = ghb_settings_get_int(ud->settings, "crop_bottom");
crop[2] = ghb_settings_get_int(ud->settings, "crop_left");
crop[3] = ghb_settings_get_int(ud->settings, "crop_right");
- titleindex = ghb_settings_get_index(ud->settings, "title");
+ titleindex = ghb_settings_get_combo_index(ud->settings, "title");
if (ghb_get_title_info (&tinfo, titleindex))
{
gint width, height;
@@ -1439,7 +1447,7 @@ crop_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
void
scale_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("scale_changed_cb ()\n");
+ g_debug("scale_changed_cb ()");
ghb_widget_to_setting(ud->settings, widget);
check_depencency(ud, widget);
clear_presets_selection(ud);
@@ -1448,13 +1456,13 @@ scale_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
gchar *text;
- text = ghb_settings_get_bool(ud->settings, "autocrop") ? "On" : "Off";
+ text = ghb_settings_get_boolean(ud->settings, "autocrop") ? "On" : "Off";
widget = GHB_WIDGET (ud->builder, "crop_auto");
gtk_label_set_text (GTK_LABEL(widget), text);
- text = ghb_settings_get_bool(ud->settings, "autoscale") ? "On" : "Off";
+ text = ghb_settings_get_boolean(ud->settings, "autoscale") ? "On" : "Off";
widget = GHB_WIDGET (ud->builder, "scale_auto");
gtk_label_set_text (GTK_LABEL(widget), text);
- text = ghb_settings_get_bool(ud->settings, "anamorphic") ? "On" : "Off";
+ text = ghb_settings_get_boolean(ud->settings, "anamorphic") ? "On" : "Off";
widget = GHB_WIDGET (ud->builder, "scale_anamorphic");
gtk_label_set_text (GTK_LABEL(widget), text);
}
@@ -1469,7 +1477,7 @@ generic_entry_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
// The changed signal is sent ... so here we are.
// I don't want to process upon every keystroke, so I prevent processing
// while the widget has focus.
- g_debug("generic_entry_changed_cb ()\n");
+ g_debug("generic_entry_changed_cb ()");
if (!GTK_WIDGET_HAS_FOCUS((GtkWidget*)entry))
{
ghb_widget_to_setting(ud->settings, (GtkWidget*)entry);
@@ -1480,7 +1488,7 @@ gboolean
generic_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
signal_user_data_t *ud)
{
- g_debug("generic_focus_out_cb ()\n");
+ g_debug("generic_focus_out_cb ()");
ghb_widget_to_setting(ud->settings, widget);
return FALSE;
}
@@ -1505,23 +1513,27 @@ x264_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
void
x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("x264_entry_changed_cb ()\n");
+ 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);
- gchar *options;
- options = (gchar*)ghb_settings_get_string(ud->settings, "x264_options");
+ 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))
{
- options = ghb_sanitize_x264opts(ud, options);
- ghb_ui_update(ud, "x264_options", options);
- ghb_x264_parse_options(ud, options);
- g_free(options);
+ 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;
}
}
@@ -1530,17 +1542,19 @@ gboolean
x264_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
signal_user_data_t *ud)
{
+ gchar *options, *sopts;
+
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);
+ options = ghb_settings_get_string(ud->settings, "x264_options");
+ sopts = ghb_sanitize_x264opts(ud, options);
ignore_options_update = TRUE;
- if (options != NULL)
+ if (sopts != NULL)
{
- ghb_ui_update(ud, "x264_options", options);
- ghb_x264_parse_options(ud, options);
- g_free(options);
+ 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;
}
@@ -1550,51 +1564,81 @@ clear_audio_list(signal_user_data_t *ud)
{
GtkTreeView *treeview;
GtkListStore *store;
- GSList *link;
+ GValue *audio_list;
- g_debug("clear_audio_list ()\n");
- while (ud->audio_settings != NULL)
+ g_debug("clear_audio_list ()");
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (audio_list == NULL)
{
- link = ud->audio_settings;
- ud->audio_settings = g_slist_remove_link(ud->audio_settings, link);
- g_hash_table_destroy((GHashTable*)link->data);
- g_slist_free_1(link);
+ audio_list = ghb_array_value_new(8);
+ ghb_settings_set_value(ud->settings, "audio_list", audio_list);
}
+ else
+ ghb_array_value_reset(audio_list, 8);
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
gtk_list_store_clear (store);
}
static void
-add_to_audio_list(signal_user_data_t *ud, GHashTable *settings)
+add_to_audio_list(signal_user_data_t *ud, GValue *settings)
{
GtkTreeView *treeview;
GtkTreeIter iter;
GtkListStore *store;
GtkTreeSelection *selection;
+ gchar *track, *codec, *br, *sr, *mix, *drc;
+ gchar *s_track, *s_codec, *s_br, *s_sr, *s_mix;
+ gdouble s_drc;
- g_debug("add_to_audio_list ()\n");
+ g_debug("add_to_audio_list ()");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
selection = gtk_tree_view_get_selection (treeview);
store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
+ track = ghb_settings_get_combo_option(settings, "audio_track"),
+ codec = ghb_settings_get_combo_option(settings, "audio_codec"),
+ br = ghb_settings_get_combo_option(settings, "audio_bitrate"),
+ sr = ghb_settings_get_combo_option(settings, "audio_rate"),
+ mix = ghb_settings_get_combo_option(settings, "audio_mix"),
+ drc = ghb_settings_get_string(settings, "audio_drc");
+
+ s_track = ghb_settings_get_string(settings, "audio_track"),
+ s_codec = ghb_settings_get_string(settings, "audio_codec"),
+ s_br = ghb_settings_get_string(settings, "audio_bitrate"),
+ s_sr = ghb_settings_get_string(settings, "audio_rate"),
+ s_mix = ghb_settings_get_string(settings, "audio_mix"),
+ s_drc = ghb_settings_get_double(settings, "audio_drc"),
+
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
// These are displayed in list
- 0, ghb_settings_get_option(settings, "audio_track"),
- 1, ghb_settings_get_option(settings, "audio_codec"),
- 2, ghb_settings_get_option(settings, "audio_bitrate"),
- 3, ghb_settings_get_option(settings, "audio_rate"),
- 4, ghb_settings_get_option(settings, "audio_mix"),
+ 0, track,
+ 1, codec,
+ 2, br,
+ 3, sr,
+ 4, mix,
// These are used to set combo box values when a list item is selected
- 5, ghb_settings_get_string(settings, "audio_drc"),
- 6, ghb_settings_get_short_opt(settings, "audio_track"),
- 7, ghb_settings_get_short_opt(settings, "audio_codec"),
- 8, ghb_settings_get_short_opt(settings, "audio_bitrate"),
- 9, ghb_settings_get_short_opt(settings, "audio_rate"),
- 10, ghb_settings_get_short_opt(settings, "audio_mix"),
+ 5, drc,
+ 6, s_track,
+ 7, s_codec,
+ 8, s_br,
+ 9, s_sr,
+ 10, s_mix,
+ 11, s_drc,
-1);
gtk_tree_selection_select_iter(selection, &iter);
+ g_free(track);
+ g_free(codec);
+ g_free(br);
+ g_free(sr);
+ g_free(mix);
+ g_free(drc);
+ g_free(s_track);
+ g_free(s_codec);
+ g_free(s_br);
+ g_free(s_sr);
+ g_free(s_mix);
}
static void
@@ -1607,14 +1651,17 @@ audio_list_refresh_selected(signal_user_data_t *ud)
GtkTreeIter iter;
gint *indices;
gint row;
- GSList *link;
- GHashTable *asettings = NULL;
+ GValue *asettings = NULL;
+ const GValue *audio_list;
- g_debug("get_selected_asettings ()\n");
+ g_debug("audio_list_refresh_selected ()");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
selection = gtk_tree_view_get_selection (treeview);
if (gtk_tree_selection_get_selected(selection, &store, &iter))
{
+ gchar *track, *codec, *br, *sr, *mix, *drc;
+ gchar *s_track, *s_codec, *s_br, *s_sr, *s_mix;
+ gdouble s_drc;
// Get the row number
treepath = gtk_tree_model_get_path (store, &iter);
indices = gtk_tree_path_get_indices (treepath);
@@ -1622,28 +1669,56 @@ audio_list_refresh_selected(signal_user_data_t *ud)
row = indices[0];
// find audio settings
if (row < 0) return;
- link = g_slist_nth(ud->audio_settings, row);
- if (link == NULL) return;
- asettings = (GHashTable*)link->data;
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (row >= ghb_array_len(audio_list))
+ return;
+ asettings = ghb_array_get_nth(audio_list, row);
+
+ track = ghb_settings_get_combo_option(asettings, "audio_track"),
+ codec = ghb_settings_get_combo_option(asettings, "audio_codec"),
+ br = ghb_settings_get_combo_option(asettings, "audio_bitrate"),
+ sr = ghb_settings_get_combo_option(asettings, "audio_rate"),
+ mix = ghb_settings_get_combo_option(asettings, "audio_mix"),
+ drc = ghb_settings_get_string(asettings, "audio_drc");
+
+ s_track = ghb_settings_get_string(asettings, "audio_track"),
+ s_codec = ghb_settings_get_string(asettings, "audio_codec"),
+ s_br = ghb_settings_get_string(asettings, "audio_bitrate"),
+ s_sr = ghb_settings_get_string(asettings, "audio_rate"),
+ s_mix = ghb_settings_get_string(asettings, "audio_mix"),
+ s_drc = ghb_settings_get_double(asettings, "audio_drc"),
+
gtk_list_store_set(GTK_LIST_STORE(store), &iter,
// These are displayed in list
- 0, ghb_settings_get_option(asettings, "audio_track"),
- 1, ghb_settings_get_option(asettings, "audio_codec"),
- 2, ghb_settings_get_option(asettings, "audio_bitrate"),
- 3, ghb_settings_get_option(asettings, "audio_rate"),
- 4, ghb_settings_get_option(asettings, "audio_mix"),
- // These are used to set combo box values when a list item is selected
- 5, ghb_settings_get_string(asettings, "audio_drc"),
- 6, ghb_settings_get_short_opt(asettings, "audio_track"),
- 7, ghb_settings_get_short_opt(asettings, "audio_codec"),
- 8, ghb_settings_get_short_opt(asettings, "audio_bitrate"),
- 9, ghb_settings_get_short_opt(asettings, "audio_rate"),
- 10, ghb_settings_get_short_opt(asettings, "audio_mix"),
+ 0, track,
+ 1, codec,
+ 2, br,
+ 3, sr,
+ 4, mix,
+ // These are used to set combo values when a list item is selected
+ 5, drc,
+ 6, s_track,
+ 7, s_codec,
+ 8, s_br,
+ 9, s_sr,
+ 10, s_mix,
+ 11, s_drc,
-1);
+ g_free(track);
+ g_free(codec);
+ g_free(br);
+ g_free(sr);
+ g_free(mix);
+ g_free(drc);
+ g_free(s_track);
+ g_free(s_codec);
+ g_free(s_br);
+ g_free(s_sr);
+ g_free(s_mix);
}
}
-static GHashTable*
+static GValue*
get_selected_asettings(signal_user_data_t *ud)
{
GtkTreeView *treeview;
@@ -1653,10 +1728,10 @@ get_selected_asettings(signal_user_data_t *ud)
GtkTreeIter iter;
gint *indices;
gint row;
- GSList *link;
- GHashTable *asettings = NULL;
+ GValue *asettings = NULL;
+ const GValue *audio_list;
- g_debug("get_selected_asettings ()\n");
+ g_debug("get_selected_asettings ()");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
selection = gtk_tree_view_get_selection (treeview);
if (gtk_tree_selection_get_selected(selection, &store, &iter))
@@ -1668,9 +1743,10 @@ get_selected_asettings(signal_user_data_t *ud)
row = indices[0];
// find audio settings
if (row < 0) return NULL;
- link = g_slist_nth(ud->audio_settings, row);
- if (link == NULL) return NULL;
- asettings = (GHashTable*)link->data;
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (row >= ghb_array_len(audio_list))
+ return NULL;
+ asettings = ghb_array_get_nth(audio_list, row);
}
return asettings;
}
@@ -1682,24 +1758,25 @@ audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t
GtkTreeIter iter;
GtkWidget *widget;
- g_debug("audio_list_selection_changed_cb ()\n");
+ g_debug("audio_list_selection_changed_cb ()");
if (gtk_tree_selection_get_selected(selection, &store, &iter))
{
- const gchar *track, *codec, *bitrate, *sample_rate, *mix, *drc;
+ const gchar *track, *codec, *bitrate, *sample_rate, *mix;
+ gdouble drc;
gtk_tree_model_get(store, &iter,
6, &track,
7, &codec,
8, &bitrate,
9, &sample_rate,
10, &mix,
- 5, &drc,
+ 11, &drc,
-1);
- ghb_ui_update(ud, "audio_track", track);
- ghb_ui_update(ud, "audio_codec", codec);
- ghb_ui_update(ud, "audio_bitrate", bitrate);
- ghb_ui_update(ud, "audio_rate", sample_rate);
- ghb_ui_update(ud, "audio_mix", mix);
- ghb_ui_update(ud, "audio_drc", drc);
+ ghb_ui_update(ud, "audio_track", ghb_string_value(track));
+ ghb_ui_update(ud, "audio_codec", ghb_string_value(codec));
+ ghb_ui_update(ud, "audio_bitrate", ghb_string_value(bitrate));
+ ghb_ui_update(ud, "audio_rate", ghb_string_value(sample_rate));
+ ghb_ui_update(ud, "audio_mix", ghb_string_value(mix));
+ ghb_ui_update(ud, "audio_drc", ghb_double_value(drc));
widget = GHB_WIDGET (ud->builder, "audio_remove");
gtk_widget_set_sensitive(widget, TRUE);
//widget = GHB_WIDGET (ud->builder, "audio_update");
@@ -1718,29 +1795,36 @@ void
audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
// Add the current audio settings to the list.
- GHashTable *asettings;
+ GValue *asettings;
GtkWidget *widget;
gint count;
+ GValue *audio_list;
- g_debug("audio_add_clicked_cb ()\n");
+ g_debug("audio_add_clicked_cb ()");
+ asettings = ghb_dict_value_new();
// Only allow up to 8 audio entries
- asettings = ghb_settings_new();
widget = GHB_WIDGET(ud->builder, "audio_track");
- ghb_settings_set(asettings, "audio_track", ghb_widget_value(widget));
+ ghb_settings_take_value(asettings, "audio_track", ghb_widget_value(widget));
widget = GHB_WIDGET(ud->builder, "audio_codec");
- ghb_settings_set(asettings, "audio_codec", ghb_widget_value(widget));
+ ghb_settings_take_value(asettings, "audio_codec", ghb_widget_value(widget));
widget = GHB_WIDGET(ud->builder, "audio_bitrate");
- ghb_settings_set(asettings, "audio_bitrate", ghb_widget_value(widget));
+ ghb_settings_take_value(asettings, "audio_bitrate", ghb_widget_value(widget));
widget = GHB_WIDGET(ud->builder, "audio_rate");
- ghb_settings_set(asettings, "audio_rate", ghb_widget_value(widget));
+ ghb_settings_take_value(asettings, "audio_rate", ghb_widget_value(widget));
widget = GHB_WIDGET(ud->builder, "audio_mix");
- ghb_settings_set(asettings, "audio_mix", ghb_widget_value(widget));
+ ghb_settings_take_value(asettings, "audio_mix", ghb_widget_value(widget));
widget = GHB_WIDGET(ud->builder, "audio_drc");
- ghb_settings_set(asettings, "audio_drc", ghb_widget_value(widget));
+ ghb_settings_take_value(asettings, "audio_drc", ghb_widget_value(widget));
- ud->audio_settings = g_slist_append(ud->audio_settings, asettings);
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (audio_list == NULL)
+ {
+ audio_list = ghb_array_value_new(8);
+ ghb_settings_set_value(ud->settings, "audio_list", audio_list);
+ }
+ ghb_array_append(audio_list, asettings);
add_to_audio_list(ud, asettings);
- count = g_slist_length(ud->audio_settings);
+ count = ghb_array_len(audio_list);
if (count >= 8)
{
gtk_widget_set_sensitive(xwidget, FALSE);
@@ -1757,9 +1841,9 @@ audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
GtkTreeIter iter, nextIter;
gint *indices;
gint row;
- GSList *link;
+ GValue *audio_list;
- g_debug("audio_remove_clicked_cb ()\n");
+ g_debug("audio_remove_clicked_cb ()");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
selection = gtk_tree_view_get_selection (treeview);
if (gtk_tree_selection_get_selected(selection, &store, &iter))
@@ -1786,13 +1870,12 @@ audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
// remove from audio settings list
if (row < 0) return;
- link = g_slist_nth(ud->audio_settings, row);
- if (link == NULL) return;
- ud->audio_settings = g_slist_remove_link(ud->audio_settings, link);
- g_hash_table_destroy((GHashTable*)link->data);
- g_slist_free_1(link);
widget = GHB_WIDGET (ud->builder, "audio_add");
gtk_widget_set_sensitive(widget, TRUE);
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (row >= ghb_array_len(audio_list))
+ return;
+ ghb_array_remove(audio_list, row);
}
}
@@ -1803,37 +1886,70 @@ audio_list_refresh(signal_user_data_t *ud)
GtkTreeIter iter;
GtkListStore *store;
gboolean done;
-
- g_debug("audio_list_refresh ()\n");
- GSList *link = ud->audio_settings;
- if (link == NULL) return;
+ gint row = 0;
+ GValue *audio_list;
+
+ g_debug("audio_list_refresh ()");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
{
do
{
- GHashTable *asettings;
+ gchar *track, *codec, *br, *sr, *mix, *drc;
+ gchar *s_track, *s_codec, *s_br, *s_sr, *s_mix;
+ gdouble s_drc;
+ GValue *asettings;
+
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ if (row >= ghb_array_len(audio_list))
+ return;
+ asettings = ghb_array_get_nth(audio_list, row);
+
+ track = ghb_settings_get_combo_option(asettings, "audio_track"),
+ codec = ghb_settings_get_combo_option(asettings, "audio_codec"),
+ br = ghb_settings_get_combo_option(asettings, "audio_bitrate"),
+ sr = ghb_settings_get_combo_option(asettings, "audio_rate"),
+ mix = ghb_settings_get_combo_option(asettings, "audio_mix"),
+ drc = ghb_settings_get_string(asettings, "audio_drc");
+
+ s_track = ghb_settings_get_string(asettings, "audio_track"),
+ s_codec = ghb_settings_get_string(asettings, "audio_codec"),
+ s_br = ghb_settings_get_string(asettings, "audio_bitrate"),
+ s_sr = ghb_settings_get_string(asettings, "audio_rate"),
+ s_mix = ghb_settings_get_string(asettings, "audio_mix"),
+ s_drc = ghb_settings_get_double(asettings, "audio_drc");
- asettings = (GHashTable*)link->data;
gtk_list_store_set(GTK_LIST_STORE(store), &iter,
// These are displayed in list
- 0, ghb_settings_get_option(asettings, "audio_track"),
- 1, ghb_settings_get_option(asettings, "audio_codec"),
- 2, ghb_settings_get_option(asettings, "audio_bitrate"),
- 3, ghb_settings_get_option(asettings, "audio_rate"),
- 4, ghb_settings_get_option(asettings, "audio_mix"),
- // These are used to set combo box values when a list item is selected
- 5, ghb_settings_get_string(asettings, "audio_drc"),
- 6, ghb_settings_get_short_opt(asettings, "audio_track"),
- 7, ghb_settings_get_short_opt(asettings, "audio_codec"),
- 8, ghb_settings_get_short_opt(asettings, "audio_bitrate"),
- 9, ghb_settings_get_short_opt(asettings, "audio_rate"),
- 10, ghb_settings_get_short_opt(asettings, "audio_mix"),
+ 0, track,
+ 1, codec,
+ 2, br,
+ 3, sr,
+ 4, mix,
+ // These are used to set combo values when an item is selected
+ 5, drc,
+ 6, s_track,
+ 7, s_codec,
+ 8, s_br,
+ 9, s_sr,
+ 10, s_mix,
+ 11, s_drc,
-1);
+ g_free(track);
+ g_free(codec);
+ g_free(br);
+ g_free(sr);
+ g_free(mix);
+ g_free(drc);
+ g_free(s_track);
+ g_free(s_codec);
+ g_free(s_br);
+ g_free(s_sr);
+ g_free(s_mix);
done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
- link = link->next;
- } while (!done && link);
+ row++;
+ } while (!done);
}
}
@@ -1844,63 +1960,75 @@ ghb_presets_list_update(signal_user_data_t *ud)
GtkTreeIter iter;
GtkListStore *store;
gboolean done;
- gint ii = 0;
- gint index;
- gchar **presets;
- gchar **descriptions;
+ GList *presets, *plink;
+ gchar *preset, *def_preset;
+ gchar *description;
gint flags, custom, def;
- g_debug("ghb_presets_list_update ()\n");
- presets = ghb_presets_get_names();
- descriptions = ghb_presets_get_descriptions();
+ g_debug("ghb_presets_list_update ()");
+ def_preset = ghb_settings_get_string(ud->settings, "default_preset");
+ plink = presets = ghb_presets_get_names();
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
{
do
{
- if ((presets != NULL) && (presets[ii] != NULL))
+ if (plink)
{
// Update row with settings data
- g_debug("Updating row\n");
- flags = ghb_preset_flags(presets[ii], &index);
- def = flags & PRESET_DEFAULT;
+ g_debug("Updating row");
+ preset = (gchar*)plink->data;
+ def = 0;
+ if (strcmp(preset, def_preset) == 0)
+ def = PRESET_DEFAULT;
+
+ description = ghb_presets_get_description(preset);
+ flags = ghb_preset_flags(preset);
custom = flags & PRESET_CUSTOM;
gtk_list_store_set(store, &iter,
- 0, presets[ii],
+ 0, preset,
1, def ? 800 : 400,
2, def ? 2 : 0,
3, custom ? "black" : "blue",
- 4, descriptions[ii],
+ 4, description,
-1);
- ii++;
+ plink = plink->next;
+ g_free(description);
done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
}
else
{
// No more settings data, remove row
- g_debug("Removing row\n");
+ g_debug("Removing row");
done = !gtk_list_store_remove(store, &iter);
}
} while (!done);
}
- while ((presets != NULL) && (presets[ii] != NULL))
+ while (plink)
{
// Additional settings, add row
- g_debug("Adding row %s\n", presets[ii]);
+ g_debug("Adding rows");
+ preset = (gchar*)plink->data;
+ def = 0;
+ if (strcmp(preset, def_preset) == 0)
+ def = PRESET_DEFAULT;
+
+ description = ghb_presets_get_description(preset);
gtk_list_store_append(store, &iter);
- flags = ghb_preset_flags(presets[ii], &index);
- def = flags & PRESET_DEFAULT;
+ flags = ghb_preset_flags(preset);
custom = flags & PRESET_CUSTOM;
- gtk_list_store_set(store, &iter, 0, presets[ii],
+ gtk_list_store_set(store, &iter, 0, preset,
1, def ? 800 : 400,
2, def ? 2 : 0,
3, custom ? "black" : "blue",
- 4, descriptions[ii],
+ 4, description,
-1);
- ii++;
+ plink = plink->next;
+ g_free(description);
}
- g_strfreev (presets);
+ g_free(def_preset);
+ g_list_free (presets);
}
void
@@ -1914,7 +2042,7 @@ ghb_select_preset(GtkBuilder *builder, const gchar *preset)
gboolean done;
gboolean foundit = FALSE;
- g_debug("select_preset()\n");
+ g_debug("select_preset()");
if (preset == NULL) return;
treeview = GTK_TREE_VIEW(GHB_WIDGET(builder, "presets_list"));
selection = gtk_tree_view_get_selection (treeview);
@@ -1943,46 +2071,11 @@ ghb_select_preset(GtkBuilder *builder, const gchar *preset)
static void
update_audio_presets(signal_user_data_t *ud)
{
- GSList *link = ud->audio_settings;
- GHashTable *asettings;
- gchar *acodec, *bitrate, *rate, *mix, *drc;
- GString *pref_acodec, *pref_bitrate, *pref_rate, *pref_mix, *pref_drc;
- pref_acodec = g_string_new("");
- pref_bitrate = g_string_new("");
- pref_rate = g_string_new("");
- pref_mix = g_string_new("");
- pref_drc = g_string_new("");
- while (link)
- {
- gchar *format = link->next ? "%s," : "%s";
- asettings = (GHashTable*)link->data;
- acodec = (gchar*)ghb_settings_get_short_opt(asettings, "audio_codec");
- g_string_append_printf( pref_acodec, format, acodec);
- bitrate = (gchar*)ghb_settings_get_string(asettings, "audio_bitrate");
- g_string_append_printf( pref_bitrate, format, bitrate);
- rate = (gchar*)ghb_settings_get_string(asettings, "audio_rate");
- g_string_append_printf( pref_rate, format, rate);
- mix = (gchar*)ghb_settings_get_short_opt(asettings, "audio_mix");
- g_string_append_printf( pref_mix, format, mix);
- drc = (gchar*)ghb_settings_get_string(asettings, "audio_drc");
- g_string_append_printf( pref_drc, format, drc);
- link = link->next;
- }
- acodec = g_string_free(pref_acodec, FALSE);
- bitrate = g_string_free(pref_bitrate, FALSE);
- rate = g_string_free(pref_rate, FALSE);
- mix = g_string_free(pref_mix, FALSE);
- drc = g_string_free(pref_drc, FALSE);
- ghb_settings_set_string(ud->settings, "pref_audio_codec", acodec);
- ghb_settings_set_string(ud->settings, "pref_audio_bitrate", bitrate);
- ghb_settings_set_string(ud->settings, "pref_audio_rate", rate);
- ghb_settings_set_string(ud->settings, "pref_audio_mix", mix);
- ghb_settings_set_string(ud->settings, "pref_audio_drc", drc);
- g_free(acodec);
- g_free(bitrate);
- g_free(rate);
- g_free(mix);
- g_free(drc);
+ g_debug("update_audio_presets");
+ const GValue *audio_list;
+
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ ghb_settings_set_value(ud->settings, "pref_audio_list", audio_list);
}
void
@@ -1992,22 +2085,23 @@ presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
GtkEntry *entry;
GtkTextView *desc;
GtkResponseType response;
- const gchar *preset = "";
+ gchar *preset;
- g_debug("presets_save_clicked_cb ()\n");
+ g_debug("presets_save_clicked_cb ()");
preset = ghb_settings_get_string (ud->settings, "preset");
// Clear the description
desc = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "preset_description"));
dialog = GHB_WIDGET(ud->builder, "preset_save_dialog");
entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "preset_name"));
gtk_entry_set_text(entry, preset);
+ g_free(preset);
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_hide(dialog);
if (response == GTK_RESPONSE_OK)
{
// save the preset
const gchar *name = gtk_entry_get_text(entry);
- g_debug("description to settings\n");
+ g_debug("description to settings");
ghb_widget_to_setting(ud->settings, GTK_WIDGET(desc));
// Construct the audio settings presets from the current audio list
update_audio_presets(ud);
@@ -2021,14 +2115,15 @@ presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
void
presets_restore_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
- g_debug("presets_restore_clicked_cb ()\n");
+ g_debug("presets_restore_clicked_cb ()");
// Reload only the standard presets
ghb_presets_reload(ud);
ghb_presets_list_update(ud);
// Updating the presets list shuffles things around
// need to make sure the proper preset is selected
- const gchar *preset = ghb_settings_get_string (ud->settings, "preset");
+ gchar *preset = ghb_settings_get_string (ud->settings, "preset");
ghb_select_preset(ud->builder, preset);
+ g_free(preset);
}
void
@@ -2037,7 +2132,7 @@ prefs_dialog_cb(GtkWidget *xwidget, signal_user_data_t *ud)
GtkWidget *dialog;
GtkResponseType response;
- g_debug("prefs_dialog_cb ()\n");
+ g_debug("prefs_dialog_cb ()");
dialog = GHB_WIDGET(ud->builder, "prefs_dialog");
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_hide(dialog);
@@ -2053,7 +2148,7 @@ presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
gchar *preset;
GtkResponseType response;
- g_debug("presets_remove_clicked_cb ()\n");
+ g_debug("presets_remove_clicked_cb ()");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
selection = gtk_tree_view_get_selection (treeview);
if (gtk_tree_selection_get_selected(selection, &store, &iter))
@@ -2084,7 +2179,7 @@ presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
// Remove the selected item
// First unselect it so that selecting the new item works properly
gtk_tree_selection_unselect_iter (selection, &iter);
- ghb_presets_remove(ud->settings, preset);
+ ghb_presets_remove(preset);
ghb_presets_list_update(ud);
ghb_select_preset(ud->builder, nextPreset);
}
@@ -2096,12 +2191,17 @@ preset_update_title_deps(signal_user_data_t *ud, ghb_title_info_t *tinfo)
{
GtkWidget *widget;
- ghb_ui_update_int (ud, "scale_width", tinfo->width - tinfo->crop[2] - tinfo->crop[3]);
+ ghb_ui_update(ud, "scale_width",
+ ghb_int64_value(tinfo->width - tinfo->crop[2] - tinfo->crop[3]));
// If anamorphic or keep_aspect, the hight will be automatically calculated
- gboolean keep_aspect = ghb_settings_get_bool(ud->settings, "keep_aspect");
- gboolean anamorphic = ghb_settings_get_bool(ud->settings, "anamorphic");
+ gboolean keep_aspect, anamorphic;
+ keep_aspect = ghb_settings_get_boolean(ud->settings, "keep_aspect");
+ anamorphic = ghb_settings_get_boolean(ud->settings, "anamorphic");
if (!(keep_aspect || anamorphic))
- ghb_ui_update_int (ud, "scale_height", tinfo->height - tinfo->crop[0] - tinfo->crop[1]);
+ {
+ ghb_ui_update(ud, "scale_height",
+ ghb_int64_value(tinfo->height - tinfo->crop[0] - tinfo->crop[1]));
+ }
// Set the limits of cropping. hb_set_anamorphic_size crashes if
// you pass it a cropped width or height == 0.
@@ -2116,12 +2216,12 @@ preset_update_title_deps(signal_user_data_t *ud, ghb_title_info_t *tinfo)
gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
widget = GHB_WIDGET (ud->builder, "crop_right");
gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
- if (ghb_settings_get_bool (ud->settings, "autocrop"))
+ if (ghb_settings_get_boolean(ud->settings, "autocrop"))
{
- ghb_ui_update_int (ud, "crop_top", tinfo->crop[0]);
- ghb_ui_update_int (ud, "crop_bottom", tinfo->crop[1]);
- ghb_ui_update_int (ud, "crop_left", tinfo->crop[2]);
- ghb_ui_update_int (ud, "crop_right", tinfo->crop[3]);
+ ghb_ui_update(ud, "crop_top", ghb_int64_value(tinfo->crop[0]));
+ ghb_ui_update(ud, "crop_bottom", ghb_int64_value(tinfo->crop[1]));
+ ghb_ui_update(ud, "crop_left", ghb_int64_value(tinfo->crop[2]));
+ ghb_ui_update(ud, "crop_right", ghb_int64_value(tinfo->crop[3]));
}
}
@@ -2134,7 +2234,7 @@ presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_
ghb_title_info_t tinfo;
GtkWidget *widget;
- g_debug("presets_list_selection_changed_cb ()\n");
+ g_debug("presets_list_selection_changed_cb ()");
widget = GHB_WIDGET (ud->builder, "presets_remove");
if (gtk_tree_selection_get_selected(selection, &store, &iter))
{
@@ -2166,7 +2266,7 @@ presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_
}
else
{
- g_debug("No selection??? Perhaps unselected.\n");
+ g_debug("No selection??? Perhaps unselected.");
gtk_widget_set_sensitive(widget, FALSE);
}
}
@@ -2177,7 +2277,7 @@ queue_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t
GtkTreeModel *store;
GtkTreeIter iter, piter;
- g_debug("queue_list_selection_changed_cb ()\n");
+ g_debug("queue_list_selection_changed_cb ()");
// A queue entry is made up of a parent and multiple
// children that are visible when expanded. When and entry
// is selected, I want the parent to be selected.
@@ -2200,7 +2300,7 @@ queue_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t
}
static void
-add_to_queue_list(signal_user_data_t *ud, job_settings_t *item)
+add_to_queue_list(signal_user_data_t *ud, GValue *settings)
{
GtkTreeView *treeview;
GtkTreeIter iter;
@@ -2209,34 +2309,37 @@ add_to_queue_list(signal_user_data_t *ud, job_settings_t *item)
gint num_pass = 1;
gint ii;
GtkTreeIter citer;
+ gchar *vcodec, *container, *acodec, *dest, *preset, *vol_name;
+ gchar *fps, *vcodec_abbr;
+ gint title, start_chapter, end_chapter, width, height, vqvalue;
+ gboolean pass2, anamorphic, round_dim, keep_aspect, vqtype, turbo;
- g_debug("update_queue_list ()\n");
- if (item == NULL) return;
+ g_debug("update_queue_list ()");
+ if (settings == NULL) return;
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
- gint title = ghb_settings_get_int(item->settings, "title");
- gint start_chapter = ghb_settings_get_int(item->settings, "start_chapter");
- gint end_chapter = ghb_settings_get_int(item->settings, "end_chapter");
- gboolean pass2 = ghb_settings_get_bool(item->settings, "two_pass");
- const gchar *vol_name = ghb_settings_get_string(item->settings, "volume_label");
- if (vol_name == NULL)
- vol_name = "No Title";
+ title = ghb_settings_get_int(settings, "title");
+ start_chapter = ghb_settings_get_int(settings, "start_chapter");
+ end_chapter = ghb_settings_get_int(settings, "end_chapter");
+ pass2 = ghb_settings_get_boolean(settings, "two_pass");
+ vol_name = ghb_settings_get_string(settings, "volume_label");
info = g_strdup_printf
- (
+ (
"<big><b>%s</b></big> (Title %d, Chapters %d through %d, %d Video %s)",
vol_name, title+1, start_chapter, end_chapter,
- pass2 ? 2:1, pass2 ? "Passes":"Pass");
+ pass2 ? 2:1, pass2 ? "Passes":"Pass"
+ );
gtk_tree_store_append(store, &iter, NULL);
gtk_tree_store_set(store, &iter, 0, "hb-queue-job", 1, info, 2, "hb-queue-delete", -1);
g_free(info);
-
- const gchar *vcodec = ghb_settings_get_option(item->settings, "video_codec");
- const gchar *container = ghb_settings_get_option(item->settings, "container");
- const gchar *acodec = ghb_settings_get_option(item->settings, "audio_codec");
- const gchar *dest = ghb_settings_get_string(item->settings, "destination");
- const gchar *preset = ghb_settings_get_string(item->settings, "preset");
+
+ vcodec = ghb_settings_get_combo_option(settings, "video_codec");
+ container = ghb_settings_get_combo_option(settings, "container");
+ acodec = ghb_settings_get_combo_option(settings, "audio_codec");
+ dest = ghb_settings_get_string(settings, "destination");
+ preset = ghb_settings_get_string(settings, "preset");
info = g_strdup_printf
(
"<b>Preset:</b> %s\n"
@@ -2248,11 +2351,12 @@ add_to_queue_list(signal_user_data_t *ud, job_settings_t *item)
gtk_tree_store_set(store, &citer, 1, info, -1);
g_free(info);
- gint width = ghb_settings_get_int(item->settings, "scale_width");
- gint height = ghb_settings_get_int(item->settings, "scale_height");
- gboolean anamorphic = ghb_settings_get_bool(item->settings, "anamorphic");
- gboolean round_dim = ghb_settings_get_bool(item->settings, "round_dimensions");
- gboolean keep_aspect = ghb_settings_get_bool(item->settings, "keep_aspect");
+ width = ghb_settings_get_int(settings, "scale_width");
+ height = ghb_settings_get_int(settings, "scale_height");
+ anamorphic = ghb_settings_get_boolean(settings, "anamorphic");
+ round_dim = ghb_settings_get_boolean(settings, "round_dimensions");
+ keep_aspect = ghb_settings_get_boolean(settings, "keep_aspect");
+
gchar *aspect_desc;
if (anamorphic)
{
@@ -2276,38 +2380,38 @@ add_to_queue_list(signal_user_data_t *ud, job_settings_t *item)
aspect_desc = "(Aspect Lost)";
}
}
- gboolean vqtype = ghb_settings_get_bool(item->settings, "vquality_type_constant");
- gint vqvalue = 0;
+ vqtype = ghb_settings_get_boolean(settings, "vquality_type_constant");
+ vqvalue = 0;
+
gchar *vq_desc = "Error";
if (!vqtype)
{
- vqtype = ghb_settings_get_bool(item->settings, "vquality_type_target");
+ vqtype = ghb_settings_get_boolean(settings, "vquality_type_target");
if (!vqtype)
{
// Has to be bitrate
- vqvalue = ghb_settings_get_int(item->settings, "video_bitrate");
+ vqvalue = ghb_settings_get_int(settings, "video_bitrate");
vq_desc = "kbps";
}
else
{
// Target file size
- vqvalue = ghb_settings_get_int(item->settings, "video_target");
+ vqvalue = ghb_settings_get_int(settings, "video_target");
vq_desc = "MB";
}
}
else
{
// Constant quality
- vqvalue = ghb_settings_get_int(item->settings, "video_quality");
+ vqvalue = ghb_settings_get_int(settings, "video_quality");
vq_desc = "% Constant Quality";
}
- const gchar *fps = ghb_settings_get_string(item->settings, "framerate");
- const gchar *vcodec_abbr = ghb_settings_get_short_opt(item->settings, "video_codec");
+ fps = ghb_settings_get_string(settings, "framerate");
+ vcodec_abbr = ghb_settings_get_string(settings, "video_codec");
gchar *extra_opts;
if (strcmp(vcodec_abbr, "x264") == 0)
{
- gchar *x264opts = ghb_build_x264opts_string(item->settings);
- g_debug("xopts (%s)\n", x264opts);
+ gchar *x264opts = ghb_build_x264opts_string(settings);
extra_opts = g_strdup_printf ("\n<b>x264 Options:</b> %s", x264opts);
g_free(x264opts);
}
@@ -2315,7 +2419,7 @@ add_to_queue_list(signal_user_data_t *ud, job_settings_t *item)
{
extra_opts = g_strdup("");
}
- gboolean turbo = ghb_settings_get_bool (item->settings, "turbo");
+ turbo = ghb_settings_get_boolean(settings, "turbo");
gchar *turbo_desc = "\n<b>Turbo:</b> Off";;
if (turbo)
{
@@ -2338,19 +2442,30 @@ add_to_queue_list(signal_user_data_t *ud, job_settings_t *item)
if (final)
{
// Add the audios
- GSList *link = item->audio_settings;
- while (link)
+ gint count, ii;
+ const GValue *audio_list;
+
+ audio_list = ghb_settings_get_value(settings, "audio_list");
+ count = ghb_array_len(audio_list);
+ for (ii = 0; ii < count; ii++)
{
- GHashTable *asettings = (GHashTable*)link->data;
- const gchar *acodec = ghb_settings_get_option(asettings, "audio_codec");
- const gchar *bitrate = ghb_settings_get_string(asettings, "audio_bitrate");
- const gchar *samplerate = ghb_settings_get_string(asettings, "audio_rate");
+ gchar *acodec, *bitrate, *samplerate, *mix;
+ GValue *asettings;
+
+ asettings = ghb_array_get_nth(audio_list, ii);
+
+ acodec = ghb_settings_get_combo_option(asettings, "audio_codec");
+ bitrate = ghb_settings_get_string(asettings, "audio_bitrate");
+ samplerate = ghb_settings_get_string(asettings, "audio_rate");
gint track = ghb_settings_get_int(asettings, "audio_track");
- const gchar *mix = ghb_settings_get_option(asettings, "audio_mix");
+ mix = ghb_settings_get_combo_option(asettings, "audio_mix");
g_string_append_printf(pass,
"\n<b>Audio:</b> %s, %s kbps, %s kHz, Track %d: %s",
acodec, bitrate, samplerate, track+1, mix);
- link = link->next;
+ g_free(acodec);
+ g_free(bitrate);
+ g_free(samplerate);
+ g_free(mix);
}
}
info = g_string_free(pass, FALSE);
@@ -2358,6 +2473,14 @@ add_to_queue_list(signal_user_data_t *ud, job_settings_t *item)
gtk_tree_store_set(store, &citer, 0, ii ? "hb-queue-pass2" : "hb-queue-pass1", 1, info, -1);
g_free(info);
}
+ g_free(fps);
+ g_free(vcodec_abbr);
+ g_free(vol_name);
+ g_free(vcodec);
+ g_free(container);
+ g_free(acodec);
+ g_free(dest);
+ g_free(preset);
g_free(extra_opts);
}
@@ -2407,17 +2530,20 @@ validate_settings(signal_user_data_t *ud)
{
// Check to see if the dest file exists or is
// already in the queue
- gchar *message;
+ gchar *message, *dest;
+ gint count, ii;
gint titleindex = ghb_settings_get_int(ud->settings, "title");
+
if (titleindex < 0) return FALSE;
- const gchar *dest = ghb_settings_get_string(ud->settings, "destination");
- GSList *link = ud->queue;
- while (link != NULL)
+ dest = ghb_settings_get_string(ud->settings, "destination");
+ count = ghb_array_len(ud->queue);
+ for (ii = 0; ii < count; ii++)
{
- job_settings_t *item;
- const gchar *filename;
- item = (job_settings_t*)link->data;
- filename = ghb_settings_get_string(item->settings, "destination");
+ GValue *js;
+ gchar *filename;
+
+ js = ghb_array_get_nth(ud->queue, ii);
+ filename = ghb_settings_get_string(js, "destination");
if (strcmp(dest, filename) == 0)
{
message = g_strdup_printf(
@@ -2427,13 +2553,15 @@ validate_settings(signal_user_data_t *ud)
dest);
if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Overwrite"))
{
+ g_free(filename);
+ g_free(dest);
g_free(message);
return FALSE;
}
g_free(message);
break;
}
- link = link->next;
+ g_free(filename);
}
gchar *destdir = g_path_get_dirname(dest);
if (!g_file_test(destdir, G_FILE_TEST_IS_DIR))
@@ -2443,6 +2571,7 @@ validate_settings(signal_user_data_t *ud)
"This is not a valid directory.",
destdir);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ g_free(dest);
g_free(message);
g_free(destdir);
return FALSE;
@@ -2454,6 +2583,7 @@ validate_settings(signal_user_data_t *ud)
"Can not read or write the directory.",
destdir);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ g_free(dest);
g_free(message);
g_free(destdir);
return FALSE;
@@ -2482,6 +2612,7 @@ validate_settings(signal_user_data_t *ud)
(guint)(size / (1024L*1024L)));
if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Proceed"))
{
+ g_free(dest);
g_free(message);
return FALSE;
}
@@ -2502,12 +2633,14 @@ validate_settings(signal_user_data_t *ud)
dest);
if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Overwrite"))
{
+ g_free(dest);
g_free(message);
return FALSE;
}
g_free(message);
g_unlink(dest);
}
+ g_free(dest);
// Validate video quality is in a reasonable range
if (!ghb_validate_vquality(ud->settings))
{
@@ -2541,34 +2674,25 @@ static gboolean
queue_add(signal_user_data_t *ud)
{
// Add settings to the queue
- job_settings_t *queue_item;
- GSList *link;
static gint unique_id = 0;
+ GValue *settings;
- g_debug("queue_add ()\n");
+ g_debug("queue_add ()");
if (!validate_settings(ud))
{
return FALSE;
}
+ if (ud->queue == NULL)
+ ud->queue = ghb_array_value_new(32);
// Make a copy of current settings to be used for the new job
- queue_item = g_malloc(sizeof(job_settings_t));
- queue_item->settings = ghb_settings_dup(ud->settings);
- queue_item->audio_settings = NULL;
- link = ud->audio_settings;
- while (link != NULL)
- {
- GHashTable *asettings;
- asettings = ghb_settings_dup((GHashTable*)link->data);
- queue_item->audio_settings =
- g_slist_append(queue_item->audio_settings, asettings);
- link = g_slist_next(link);
- }
- queue_item->chapter_list = g_strdupv(ud->chapter_list);
- ud->queue = g_slist_append(ud->queue, queue_item);
- add_to_queue_list(ud, queue_item);
- ghb_add_job (queue_item, unique_id);
- queue_item->unique_id = unique_id;
- queue_item->status = GHB_QUEUE_PENDING;
+ settings = ghb_value_dup(ud->settings);
+ ghb_settings_set_int(settings, "job_unique_id", unique_id);
+ ghb_settings_set_int(settings, "job_status", GHB_QUEUE_PENDING);
+
+ ghb_array_append(ud->queue, settings);
+ add_to_queue_list(ud, settings);
+ ghb_add_job (settings, unique_id);
+
unique_id++;
return TRUE;
}
@@ -2576,7 +2700,7 @@ queue_add(signal_user_data_t *ud)
void
queue_add_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("queue_add_clicked_cb ()\n");
+ g_debug("queue_add_clicked_cb ()");
queue_add(ud);
}
@@ -2610,15 +2734,12 @@ queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
GtkTreeModel *store;
GtkTreeIter iter;
gint row;
- GSList *link;
gint *indices;
- job_settings_t *queue_item;
gint unique_id;
+ GValue *settings;
+ gint status;
- g_debug("queue_remove_clicked_cb ()\n");
- g_debug("ud %p\n", ud);
- g_debug("ud->builder %p\n", ud->builder);
-
+ g_debug("queue_remove_clicked_cb ()");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
store = gtk_tree_view_get_model(treeview);
treepath = gtk_tree_path_new_from_string (path);
@@ -2631,10 +2752,11 @@ queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
// indices since this points into treepath somewhere.
gtk_tree_path_free (treepath);
if (row < 0) return;
- link = g_slist_nth(ud->queue, row);
- if (link == NULL) return;
- queue_item = (job_settings_t*)link->data;
- if (queue_item->status == GHB_QUEUE_RUNNING)
+ if (row >= ghb_array_len(ud->queue))
+ return;
+ settings = ghb_array_get_nth(ud->queue, row);
+ status = ghb_settings_get_int(settings, "job_status");
+ if (status == GHB_QUEUE_RUNNING)
{
// Ask if wants to stop encode.
if (!cancel_encode(NULL))
@@ -2643,24 +2765,10 @@ queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
}
}
// Remove the selected item
- g_debug(" should be removing from treestore\n");
gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
// Remove the corresponding item from the queue list
- ud->queue = g_slist_remove_link(ud->queue, link);
- g_slist_free_1(link);
- g_hash_table_destroy(queue_item->settings);
- link = queue_item->audio_settings;
- while (link != NULL)
- {
- GSList *nextlink;
- g_hash_table_destroy((GHashTable*)link->data);
- nextlink = g_slist_next(link);
- g_slist_free_1(link);
- link = nextlink;
- }
- g_strfreev (queue_item->chapter_list);
- unique_id = queue_item->unique_id;
- g_free(queue_item);
+ unique_id = ghb_settings_get_int(settings, "job_unique_id");
+ ghb_array_remove(ud->queue, row);
ghb_remove_job(unique_id);
}
else
@@ -2670,24 +2778,25 @@ queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
}
static gint
-find_queue_item(GSList *queue, gint unique_id, job_settings_t **job)
+find_queue_job(GValue *queue, gint unique_id, GValue **job)
{
- job_settings_t *js;
- gint index = -1;
+ GValue *js;
+ gint ii, count;
+ gint job_unique_id;
- while (queue != NULL)
+ *job = NULL;
+ count = ghb_array_len(queue);
+ for (ii = 0; ii < count; ii++)
{
- index++;
- js = (job_settings_t*)queue->data;
- if (js->unique_id == unique_id)
+ js = ghb_array_get_nth(queue, ii);
+ job_unique_id = ghb_settings_get_int(js, "job_unique_id");
+ if (job_unique_id == unique_id)
{
*job = js;
- return index;
+ return ii;
}
- queue = queue->next;
}
- *job = NULL;
- return index;
+ return -1;
}
static void
@@ -2724,7 +2833,7 @@ ghb_backend_events(signal_user_data_t *ud)
gchar *status_str;
GtkProgressBar *progress;
gint titleindex;
- job_settings_t *js;
+ GValue *js;
static gint current_id = -1;
gint index;
GtkTreeView *treeview;
@@ -2759,7 +2868,7 @@ ghb_backend_events(signal_user_data_t *ud)
ghb_update_ui_combo_box(ud->builder, "title", 0, FALSE);
titleindex = ghb_longest_title();
- ghb_ui_update_int(ud, "title", titleindex);
+ ghb_ui_update(ud, "title", ghb_int64_value(titleindex));
// Are there really any titles.
if (!ghb_get_title_info(&tinfo, titleindex))
@@ -2772,6 +2881,12 @@ ghb_backend_events(signal_user_data_t *ud)
ghb_clear_state(GHB_STATE_SCANDONE);
queue_buttons_grey(ud, (0 != (status.state & GHB_STATE_WORKING)));
}
+ else if (status.state & GHB_STATE_PAUSED)
+ {
+ status_str = g_strdup_printf ("Paused");
+ gtk_progress_bar_set_text (progress, status_str);
+ g_free(status_str);
+ }
else if (status.state & GHB_STATE_WORKING)
{
if(status.seconds > -1)
@@ -2799,7 +2914,7 @@ ghb_backend_events(signal_user_data_t *ud)
{
work_started = FALSE;
queue_buttons_grey(ud, FALSE);
- index = find_queue_item(ud->queue, current_id, &js);
+ index = find_queue_job(ud->queue, current_id, &js);
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
switch( status.error )
@@ -2808,9 +2923,10 @@ ghb_backend_events(signal_user_data_t *ud)
gtk_progress_bar_set_text( progress, "Rip done!" );
if (js != NULL)
{
- js->status = GHB_QUEUE_DONE;
+ ghb_settings_set_int(js, "job_status", GHB_QUEUE_DONE);
gchar *path = g_strdup_printf ("%d", index);
- if (gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL(store), &iter, path))
+ if (gtk_tree_model_get_iter_from_string(
+ GTK_TREE_MODEL(store), &iter, path))
{
gtk_tree_store_set(store, &iter, 0, "hb-complete", -1);
}
@@ -2821,9 +2937,10 @@ ghb_backend_events(signal_user_data_t *ud)
gtk_progress_bar_set_text( progress, "Rip canceled." );
if (js != NULL)
{
- js->status = GHB_QUEUE_CANCELED;
+ ghb_settings_set_int(js, "job_status", GHB_QUEUE_CANCELED);
gchar *path = g_strdup_printf ("%d", index);
- if (gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL(store), &iter, path))
+ if (gtk_tree_model_get_iter_from_string(
+ GTK_TREE_MODEL(store), &iter, path))
{
gtk_tree_store_set(store, &iter, 0, "hb-canceled", -1);
}
@@ -2834,9 +2951,10 @@ ghb_backend_events(signal_user_data_t *ud)
gtk_progress_bar_set_text( progress, "Rip failed.");
if (js != NULL)
{
- js->status = GHB_QUEUE_CANCELED;
+ ghb_settings_set_int(js, "job_status", GHB_QUEUE_CANCELED);
gchar *path = g_strdup_printf ("%d", index);
- if (gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL(store), &iter, path))
+ if (gtk_tree_model_get_iter_from_string(
+ GTK_TREE_MODEL(store), &iter, path))
{
gtk_tree_store_set(store, &iter, 0, "hb-canceled", -1);
}
@@ -2847,12 +2965,6 @@ ghb_backend_events(signal_user_data_t *ud)
gtk_progress_bar_set_fraction (progress, 1.0);
ghb_clear_state(GHB_STATE_WORKDONE);
}
- else if (status.state & GHB_STATE_PAUSED)
- {
- status_str = g_strdup_printf ("Paused");
- gtk_progress_bar_set_text (progress, status_str);
- g_free(status_str);
- }
else if (status.state & GHB_STATE_MUXING)
{
gtk_progress_bar_set_text(progress, "Muxing: this may take awhile...");
@@ -2866,28 +2978,32 @@ ghb_backend_events(signal_user_data_t *ud)
}
if (status.unique_id != current_id)
{
- index = find_queue_item(ud->queue, current_id, &js);
+ index = find_queue_job(ud->queue, current_id, &js);
if (js != NULL)
{
- js->status = GHB_QUEUE_DONE;
+ ghb_settings_set_int(js, "job_status", GHB_QUEUE_DONE);
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
gchar *path = g_strdup_printf ("%d", index);
- if (gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL(store), &iter, path))
+ if (gtk_tree_model_get_iter_from_string(
+ GTK_TREE_MODEL(store), &iter, path))
{
gtk_tree_store_set(store, &iter, 0, "hb-complete", -1);
}
g_free(path);
}
- index = find_queue_item(ud->queue, status.unique_id, &js);
+ index = find_queue_job(ud->queue, status.unique_id, &js);
if (js != NULL)
{
- js->status = GHB_QUEUE_RUNNING;
+ ghb_settings_set_int(js, "job_status", GHB_QUEUE_RUNNING);
current_id = status.unique_id;
}
}
- index = find_queue_item(ud->queue, status.unique_id, &js);
+ else
+ {
+ index = find_queue_job(ud->queue, status.unique_id, &js);
+ }
if (index >= 0)
{
gchar working_icon[] = "hb-working0";
@@ -2896,7 +3012,8 @@ ghb_backend_events(signal_user_data_t *ud)
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
gchar *path = g_strdup_printf ("%d", index);
- if (gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL(store), &iter, path))
+ if (gtk_tree_model_get_iter_from_string(
+ GTK_TREE_MODEL(store), &iter, path))
{
gtk_tree_store_set(store, &iter, 0, working_icon, -1);
}
@@ -2913,14 +3030,18 @@ ghb_timer_cb(gpointer data)
ghb_backend_events(ud);
if (update_default_destination)
{
- const gchar *dest = ghb_settings_get_string(ud->settings, "destination");
- gchar *dest_dir = g_path_get_dirname (dest);
- const gchar *def_dest = ghb_settings_get_string(ud->settings, "destination_dir");
+ gchar *dest, *dest_dir, *def_dest;
+ dest = ghb_settings_get_string(ud->settings, "destination");
+ dest_dir = g_path_get_dirname (dest);
+ def_dest = ghb_settings_get_string(ud->settings, "destination_dir");
if (strcmp(dest_dir, def_dest) != 0)
{
ghb_settings_set_string (ud->settings, "destination_dir", dest_dir);
ghb_pref_save (ud->settings, "destination_dir");
}
+ g_free(dest);
+ g_free(dest_dir);
+ g_free(def_dest);
update_default_destination = FALSE;
}
if (update_preview)
@@ -2991,10 +3112,10 @@ ghb_log_cb(GIOChannel *source, GIOCondition cond, gpointer data)
{
// This should never happen, but if it does I would get into an
// infinite loop. Returning false removes this callback.
- g_warning("Error while reading activity from pipe\n");
+ g_warning("Error while reading activity from pipe");
if (gerror != NULL)
{
- g_warning("%s\n", gerror->message);
+ g_warning("%s", gerror->message);
g_error_free (gerror);
}
return FALSE;
@@ -3068,7 +3189,7 @@ show_presets_toggled_cb(GtkToggleButton *button, signal_user_data_t *ud)
GtkWidget *widget;
GtkWindow *hb_window;
- g_debug("show_presets_clicked_cb ()\n");
+ g_debug("show_presets_clicked_cb ()");
widget = GHB_WIDGET (ud->builder, "presets_frame");
if (gtk_toggle_button_get_active(button))
{
@@ -3111,15 +3232,16 @@ update_chapter_list(signal_user_data_t *ud)
GtkTreeIter iter;
GtkListStore *store;
gboolean done;
- gchar **chapters;
+ GValue *chapters;
gint titleindex, ii;
+ gint count;
- g_debug("update_chapter_list ()\n");
- titleindex = ghb_settings_get_index(ud->settings, "title");
+ g_debug("update_chapter_list ()");
+ titleindex = ghb_settings_get_combo_index(ud->settings, "title");
chapters = ghb_get_chapters(titleindex);
- if (ud->chapter_list != NULL)
- g_strfreev (ud->chapter_list);
- ud->chapter_list = chapters;
+ count = ghb_array_len(chapters);
+ if (chapters)
+ ghb_settings_set_value(ud->settings, "chapter_list", chapters);
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "chapters_list"));
store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
@@ -3128,54 +3250,85 @@ update_chapter_list(signal_user_data_t *ud)
{
do
{
- if (chapters != NULL && chapters[ii])
+
+ if (ii < count)
{
+ gchar *chapter;
+
// Update row with settings data
- g_debug("Updating row\n");
+ g_debug("Updating row");
+ chapter = ghb_value_string(ghb_array_get_nth(chapters, ii));
gtk_list_store_set(store, &iter,
0, ii+1,
- 1, chapters[ii],
+ 1, chapter,
2, TRUE,
-1);
+ g_free(chapter);
ii++;
done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
}
else
{
// No more settings data, remove row
- g_debug("Removing row\n");
+ g_debug("Removing row");
done = !gtk_list_store_remove(store, &iter);
}
} while (!done);
}
- while (chapters != NULL && chapters[ii])
+ while (ii < count)
{
+ gchar *chapter;
+
// Additional settings, add row
- g_debug("Adding row\n");
- g_debug("%d -- %s\n", ii, chapters[ii]);
+ g_debug("Adding row");
+ chapter = ghb_value_string(ghb_array_get_nth(chapters, ii));
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, ii+1,
- 1, chapters[ii],
+ 1, chapter,
2, TRUE,
-1);
+ g_free(chapter);
ii++;
}
}
+static GtkTreePath *nextPath = NULL;
+static gboolean chapter_selection_changed = FALSE;
+
+static gboolean
+next_cell(signal_user_data_t *ud)
+{
+ GtkTreeView *treeview;
+ GtkTreeViewColumn *column;
+
+ if (nextPath)
+ {
+ if (!chapter_selection_changed)
+ {
+ treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "chapters_list"));
+ column = gtk_tree_view_get_column(treeview, 1);
+ gtk_tree_view_set_cursor(treeview, nextPath, column, TRUE);
+ }
+ gtk_tree_path_free(nextPath);
+ nextPath = NULL;
+ }
+ chapter_selection_changed = FALSE;
+ return FALSE;
+}
+
void
chapter_edited_cb(GtkCellRendererText *cell, gchar *path, gchar *text, signal_user_data_t *ud)
{
GtkTreePath *treepath;
GtkListStore *store;
GtkTreeView *treeview;
- GtkTreeViewColumn *column;
GtkTreeIter iter;
gint index;
- g_debug("chapter_edited_cb ()\n");
- g_debug("path (%s)\n", path);
- g_debug("text (%s)\n", text);
+ g_debug("chapter_edited_cb ()");
+ g_debug("path (%s)", path);
+ g_debug("text (%s)", text);
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "chapters_list"));
store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
treepath = gtk_tree_path_new_from_string (path);
@@ -3186,28 +3339,36 @@ chapter_edited_cb(GtkCellRendererText *cell, gchar *path, gchar *text, signal_us
2, TRUE,
-1);
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &index, -1);
- g_free(ud->chapter_list[index-1]);
- ud->chapter_list[index-1] = g_strdup(text);
+
+ GValue *chapters;
+ GValue *chapter;
+
+ chapters = ghb_settings_get_value(ud->settings, "chapter_list");
+ chapter = ghb_array_get_nth(chapters, index-1);
+ g_value_set_string(chapter, text);
if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter))
{
- column = gtk_tree_view_get_column(treeview, 1);
- treepath = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
- gtk_tree_view_set_cursor(treeview, treepath, column, TRUE);
- gtk_tree_path_free (treepath);
+ nextPath = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
+ chapter_selection_changed = FALSE;
+ // When a cell has been edited, I want to advance to the
+ // next cell and start editing it automaitcally.
+ // Unfortunately, we may not be in a state here where
+ // editing is allowed. This happens when the user selects
+ // a new cell with the mouse instead of just hitting enter.
+ // Some kind of Gtk quirk. widget_editable==NULL assertion.
+ // Editing is enabled again once the current event has been
+ // processed. So I'm queueing up a callback to be called
+ // when things go idle. There, I will advance to the next
+ // cell and initiate editing.
+ g_idle_add((GSourceFunc)next_cell, ud);
}
}
void
chapter_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
{
- GtkTreeModel *store;
- GtkTreeIter iter;
-
- g_debug("chapter_list_selection_changed_cb ()\n");
- if (gtk_tree_selection_get_selected(selection, &store, &iter))
- {
- // What to do??
- }
+ g_debug("chapter_list_selection_changed_cb ()");
+ chapter_selection_changed = TRUE;
}
void
@@ -3218,7 +3379,7 @@ queue_list_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, GtkCel
column = gtk_tree_view_get_column (GTK_TREE_VIEW(widget), 0);
width = gtk_tree_view_column_get_width(column);
- g_debug("col width %d alloc width %d\n", width, allocation->width);
+ g_debug("col width %d alloc width %d", width, allocation->width);
// Set new wrap-width. Shave a little off to accomidate the icons
// that share this column.
if (width >= 564) // Don't allow below a certain size
@@ -3230,7 +3391,7 @@ preview_button_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
gint titleindex = ghb_settings_get_int(ud->settings, "title");
if (titleindex < 0) return;
- g_debug("titleindex %d\n", titleindex);
+ g_debug("titleindex %d", titleindex);
GtkWidget *widget = GHB_WIDGET (ud->builder, "preview_window");
gtk_widget_show (widget);
@@ -3245,15 +3406,15 @@ preview_frame_value_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
void
preview_button_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, signal_user_data_t *ud)
{
- g_debug("-------------------------------allocate %d x %d\n", allocation->width, allocation->height);
+ g_debug("-------------------------------allocate %d x %d", allocation->width, allocation->height);
if (preview_button_width == allocation->width &&
preview_button_height == allocation->height)
{
// Nothing to do. Bug out.
- g_debug("nothing to do\n");
+ g_debug("nothing to do");
return;
}
- g_debug("-------------------------------prev allocate %d x %d\n", preview_button_width, preview_button_height);
+ g_debug("-------------------------------prev allocate %d x %d", preview_button_width, preview_button_height);
preview_button_width = allocation->width;
preview_button_height = allocation->height;
set_preview_image(ud);
@@ -3262,19 +3423,22 @@ preview_button_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, si
void
queue_start_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
- GSList *link = ud->queue;
- job_settings_t *job;
+ GValue *js;
gboolean running = FALSE;
- while (link != NULL)
+ gint count, ii;
+ gint status;
+
+ count = ghb_array_len(ud->queue);
+ for (ii = 0; ii < count; ii++)
{
- job = (job_settings_t*)link->data;
- if ((job->status == GHB_QUEUE_RUNNING) ||
- (job->status == GHB_QUEUE_PENDING))
+ js = ghb_array_get_nth(ud->queue, ii);
+ status = ghb_settings_get_int(js, "job_status");
+ if ((status == GHB_QUEUE_RUNNING) ||
+ (status == GHB_QUEUE_PENDING))
{
running = TRUE;
break;
}
- link = link->next;
}
if (!running)
{
@@ -3333,7 +3497,7 @@ void
ghb_hbfd(signal_user_data_t *ud, gboolean hbfd)
{
GtkWidget *widget;
- g_debug("ghb_hbfd\n");
+ g_debug("ghb_hbfd");
widget = GHB_WIDGET(ud->builder, "queue_pause1");
set_visible(widget, !hbfd);
widget = GHB_WIDGET(ud->builder, "queue_add");
@@ -3363,9 +3527,9 @@ ghb_hbfd(signal_user_data_t *ud, gboolean hbfd)
void
hbfd_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("hbfd_toggled_cb\n");
+ g_debug("hbfd_toggled_cb");
ghb_widget_to_setting (ud->settings, widget);
- gboolean hbfd = ghb_settings_get_bool(ud->settings, "hbfd");
+ gboolean hbfd = ghb_settings_get_boolean(ud->settings, "hbfd");
ghb_hbfd(ud, hbfd);
ghb_pref_save(ud->settings, "hbfd");
}
@@ -3373,7 +3537,7 @@ hbfd_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
void
pref_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("pref_changed_cb\n");
+ g_debug("pref_changed_cb");
ghb_widget_to_setting (ud->settings, widget);
const gchar *name = gtk_widget_get_name(widget);
ghb_pref_save(ud->settings, name);
@@ -3382,12 +3546,12 @@ pref_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
void
tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("tweaks_changed_cb\n");
+ g_debug("tweaks_changed_cb");
ghb_widget_to_setting (ud->settings, widget);
const gchar *name = gtk_widget_get_name(widget);
ghb_pref_save(ud->settings, name);
- gboolean tweaks = ghb_settings_get_bool(ud->settings, "allow_tweaks");
+ gboolean tweaks = ghb_settings_get_boolean(ud->settings, "allow_tweaks");
widget = GHB_WIDGET(ud->builder, "deinterlace");
tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
widget = GHB_WIDGET(ud->builder, "tweak_deinterlace");
@@ -3399,35 +3563,38 @@ tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
!tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
if (tweaks)
{
- const gchar *str;
- str = ghb_settings_get_short_opt(ud->settings, "deinterlace");
- ghb_ui_update(ud, "tweak_deinterlace", str);
- str = ghb_settings_get_short_opt(ud->settings, "denoise");
- ghb_ui_update(ud, "tweak_denoise", str);
+ const GValue *value;
+ value = ghb_settings_get_value(ud->settings, "deinterlace");
+ ghb_ui_update(ud, "tweak_deinterlace", value);
+ value = ghb_settings_get_value(ud->settings, "denoise");
+ ghb_ui_update(ud, "tweak_denoise", value);
}
else
{
- const gchar *str;
- str = ghb_settings_get_short_opt(ud->settings, "tweak_deinterlace");
- ghb_ui_update(ud, "deinterlace", str);
- str = ghb_settings_get_short_opt(ud->settings, "tweak_denoise");
- ghb_ui_update(ud, "denoise", str);
+ const GValue *value;
+ value = ghb_settings_get_value(ud->settings, "tweak_deinterlace");
+ ghb_ui_update(ud, "deinterlace", value);
+ value = ghb_settings_get_value(ud->settings, "tweak_denoise");
+ ghb_ui_update(ud, "denoise", value);
}
}
void
hbfd_feature_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("hbfd_feature_changed_cb\n");
+ g_debug("hbfd_feature_changed_cb");
ghb_widget_to_setting (ud->settings, widget);
const gchar *name = gtk_widget_get_name(widget);
ghb_pref_save(ud->settings, name);
- gboolean hbfd = ghb_settings_get_bool(ud->settings, "hbfd_feature");
+ gboolean hbfd = ghb_settings_get_boolean(ud->settings, "hbfd_feature");
GtkAction *action;
- gint val;
- val = ghb_settings_get_int(ud->settings, "hbfd");
- ghb_ui_update_int(ud, "hbfd", hbfd && val);
+ if (hbfd)
+ {
+ const GValue *val;
+ val = ghb_settings_get_value(ud->settings, "hbfd");
+ ghb_ui_update(ud, "hbfd", val);
+ }
action = GHB_ACTION (ud->builder, "hbfd");
gtk_action_set_visible(action, hbfd);
}
@@ -3569,7 +3736,7 @@ dbus_init (void)
dbus_error_init (&error);
if (!(dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
- g_debug ("could not get system bus: %s\n", error.message);
+ g_debug ("could not get system bus: %s", error.message);
dbus_error_free (&error);
return FALSE;
}
@@ -3637,13 +3804,13 @@ tweak_setting_cb(
gboolean allow_tweaks;
g_debug("press %d %d", event->type, event->button);
- allow_tweaks = ghb_settings_get_bool (ud->settings, "allow_tweaks");
+ allow_tweaks = ghb_settings_get_boolean(ud->settings, "allow_tweaks");
if (allow_tweaks && event->type == GDK_BUTTON_PRESS && event->button == 3)
{ // Its a right mouse click
GtkWidget *dialog;
GtkEntry *entry;
GtkResponseType response;
- const gchar *tweak = NULL;
+ gchar *tweak = NULL;
name = gtk_widget_get_name(widget);
if (g_str_has_prefix(name, "tweak_"))
@@ -3660,12 +3827,15 @@ tweak_setting_cb(
gtk_window_set_title(GTK_WINDOW(dialog), tweak_name);
entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "tweak_setting"));
if (tweak)
+ {
gtk_entry_set_text(entry, tweak);
+ g_free(tweak);
+ }
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_hide(dialog);
if (response == GTK_RESPONSE_OK)
{
- tweak = gtk_entry_get_text(entry);
+ tweak = (gchar*)gtk_entry_get_text(entry);
if (ghb_validate_filter_string(tweak, -1))
ghb_settings_set_string(ud->settings, tweak_name, tweak);
else
diff --git a/gtk/src/callbacks.h b/gtk/src/callbacks.h
index 3e4359e4f..652c6ae53 100644
--- a/gtk/src/callbacks.h
+++ b/gtk/src/callbacks.h
@@ -33,11 +33,15 @@ void ghb_presets_list_update(signal_user_data_t *ud);
gboolean ghb_timer_cb(gpointer data);
gboolean ghb_log_cb(GIOChannel *source, GIOCondition cond, gpointer data);
void ghb_select_preset(GtkBuilder *builder, const gchar *preset);
-void debug_log_handler(const gchar *domain, GLogLevelFlags flags, const gchar *msg, gpointer ud);
+void debug_log_handler(
+ const gchar *domain, GLogLevelFlags flags, const gchar *msg, gpointer ud);
void ghb_hbfd(signal_user_data_t *ud, gboolean hbfd);
void ghb_file_menu_add_dvd(signal_user_data_t *ud);
void ghb_hal_init();
-gboolean ghb_message_dialog(GtkMessageType type, const gchar *message, const gchar *no, const gchar *yes);
+gboolean ghb_message_dialog(
+ GtkMessageType type, const gchar *message,
+ const gchar *no, const gchar *yes);
+void ghb_init_dep_map();
#endif // _CALLBACKS_H_
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index bba5cac61..7edeb4ca5 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -31,6 +31,7 @@
#include "hb-backend.h"
#include "settings.h"
#include "callbacks.h"
+#include "values.h"
typedef struct
{
@@ -416,7 +417,7 @@ ghb_version()
void
ghb_vquality_range(signal_user_data_t *ud, gint *min, gint *max)
{
- if (ghb_settings_get_bool(ud->settings, "directqp"))
+ if (ghb_settings_get_boolean(ud->settings, "directqp"))
{
gint vcodec = ghb_settings_get_int(ud->settings, "video_codec");
// Only x264 and ffmpeg currently support direct qp/crf entry
@@ -444,21 +445,43 @@ ghb_vquality_range(signal_user_data_t *ud, gint *min, gint *max)
}
gint
-ghb_lookup_acodec(const gchar *acodec)
+ghb_lookup_acodec(const GValue *acodec)
{
gint ii;
+ gchar *str;
+ str = ghb_value_string(acodec);
for (ii = 0; ii < acodec_opts.count; ii++)
{
- if (strcmp(acodec_opts.map[ii].shortOpt, acodec) == 0)
+ if (strcmp(acodec_opts.map[ii].shortOpt, str) == 0)
{
return acodec_opts.map[ii].ivalue;
}
}
+ g_free(str);
return HB_ACODEC_FAAC;
}
gint
+ghb_lookup_mix(const GValue *mix)
+{
+ gint ii;
+ gchar *str;
+
+ str = ghb_value_string(mix);
+ for (ii = 0; ii < hb_audio_mixdowns_count; ii++)
+ {
+ if (strcmp(hb_audio_mixdowns[ii].short_name, str) == 0)
+ {
+ return hb_audio_mixdowns[ii].amixdown;
+ }
+ }
+ g_free(str);
+ return HB_AMIXDOWN_DOLBYPLII;
+}
+
+#if 0
+gint
ghb_lookup_bitrate(const gchar *bitrate)
{
gint ii;
@@ -490,21 +513,6 @@ ghb_lookup_rate(const gchar *rate)
return 0;
}
-gint
-ghb_lookup_mix(const gchar *mix)
-{
- gint ii;
-
- for (ii = 0; ii < hb_audio_mixdowns_count; ii++)
- {
- if (strcmp(hb_audio_mixdowns[ii].short_name, mix) == 0)
- {
- return hb_audio_mixdowns[ii].amixdown;
- }
- }
- return HB_AMIXDOWN_DOLBYPLII;
-}
-
gdouble
ghb_lookup_drc(const gchar *drc)
{
@@ -514,47 +522,46 @@ ghb_lookup_drc(const gchar *drc)
if (dval > 4.0) dval = 4.0;
return dval;
}
+#endif
-static setting_value_t*
+static GValue*
get_acodec_value(gint val)
{
- setting_value_t *value = NULL;
+ GValue *value = NULL;
gint ii;
for (ii = 0; ii < acodec_opts.count; ii++)
{
if (acodec_opts.map[ii].ivalue == val)
{
- value = g_malloc(sizeof(setting_value_t));
- value->option = g_strdup(acodec_opts.map[ii].option);
- value->shortOpt = g_strdup(acodec_opts.map[ii].shortOpt);
- value->svalue = g_strdup(acodec_opts.map[ii].svalue);
- value->index = ii;
- value->ivalue = acodec_opts.map[ii].ivalue;
- value->dvalue = acodec_opts.map[ii].dvalue;
+ value = ghb_combo_value_new(
+ ii,
+ acodec_opts.map[ii].option,
+ acodec_opts.map[ii].shortOpt,
+ acodec_opts.map[ii].svalue,
+ acodec_opts.map[ii].ivalue);
break;
}
}
return value;
}
-static setting_value_t*
+static GValue*
get_amix_value(gint val)
{
- setting_value_t *value = NULL;
+ GValue *value = NULL;
gint ii;
for (ii = 0; ii < hb_audio_mixdowns_count; ii++)
{
if (hb_audio_mixdowns[ii].amixdown == val)
{
- value = g_malloc(sizeof(setting_value_t));
- value->option = g_strdup(hb_audio_mixdowns[ii].human_readable_name);
- value->shortOpt = g_strdup(hb_audio_mixdowns[ii].short_name);
- value->svalue = g_strdup(hb_audio_mixdowns[ii].internal_name);
- value->index = ii;
- value->ivalue = hb_audio_mixdowns[ii].amixdown;
- value->dvalue = hb_audio_mixdowns[ii].amixdown;
+ value = ghb_combo_value_new(
+ ii,
+ hb_audio_mixdowns[ii].human_readable_name,
+ hb_audio_mixdowns[ii].short_name,
+ hb_audio_mixdowns[ii].internal_name,
+ hb_audio_mixdowns[ii].amixdown);
break;
}
}
@@ -1463,13 +1470,13 @@ static const char * turbo_opts =
// Construct the x264 options string
// The result is allocated, so someone must free it at some point.
gchar*
-ghb_build_x264opts_string(GHashTable *settings)
+ghb_build_x264opts_string(GValue *settings)
{
gchar *result;
- const gchar *opts = ghb_settings_get_string(settings, "x264_options");
+ gchar *opts = ghb_settings_get_string(settings, "x264_options");
if (opts != NULL)
{
- result = g_strdup(opts);
+ result = opts;
}
else
{
@@ -1478,14 +1485,14 @@ ghb_build_x264opts_string(GHashTable *settings)
return result;
}
-gchar **
+GValue*
ghb_get_chapters(gint titleindex)
{
hb_list_t * list;
hb_title_t * title;
hb_chapter_t * chapter;
gint count, ii;
- gchar **result = NULL;
+ GValue *chapters = NULL;
g_debug("ghb_get_chapters (title = %d)\n", titleindex);
if (h == NULL) return NULL;
@@ -1493,36 +1500,41 @@ ghb_get_chapters(gint titleindex)
title = (hb_title_t*)hb_list_item( list, titleindex );
if (title == NULL) return NULL;
count = hb_list_count( title->list_chapter );
- result = g_malloc((count+1) * sizeof(gchar*));
+ chapters = ghb_array_value_new(count);
for (ii = 0; ii < count; ii++)
{
chapter = hb_list_item(title->list_chapter, ii);
if (chapter == NULL) break;
if (chapter->title == NULL || chapter->title[0] == 0)
- result[ii] = g_strdup_printf ("Chapter %2d", ii);
+ {
+ gchar *str;
+ str = g_strdup_printf ("Chapter %2d", ii+1);
+ ghb_array_append(chapters, ghb_string_value_new(str));
+ g_free(str);
+ }
else
- result[ii] = g_strdup(chapter->title);
+ {
+ ghb_array_append(chapters, ghb_string_value_new(chapter->title));
+ }
}
- result[ii] = NULL;
- return result;
+ return chapters;
}
gboolean
-ghb_ac3_in_audio_list(GSList *audio_list)
+ghb_ac3_in_audio_list(const GValue *audio_list)
{
- GSList *link;
+ gint count, ii;
- link = audio_list;
- while (link != NULL)
+ count = ghb_array_len(audio_list);
+ for (ii = 0; ii < count; ii++)
{
- GHashTable *asettings;
+ GValue *asettings;
gint acodec;
- asettings = (GHashTable*)link->data;
+ asettings = ghb_array_get_nth(audio_list, ii);
acodec = ghb_settings_get_int(asettings, "audio_codec");
if (acodec == HB_ACODEC_AC3)
return TRUE;
- link = link->next;
}
return FALSE;
}
@@ -1756,7 +1768,6 @@ ghb_set_scale(signal_user_data_t *ud, gint mode)
hb_list_t * list;
hb_title_t * title;
hb_job_t * job;
- GHashTable *settings = ud->settings;
gboolean keep_aspect, round_dims, anamorphic;
gboolean autocrop, autoscale, noscale;
gint crop[4], width, height, par_width, par_height;
@@ -1780,21 +1791,21 @@ ghb_set_scale(signal_user_data_t *ud, gint mode)
/* No valid title, stop right there */
return;
}
- gint titleindex = ghb_settings_get_index(settings, "title");
+ gint titleindex = ghb_settings_get_int(ud->settings, "title");
title = hb_list_item( list, titleindex );
if (title == NULL) return;
job = title->job;
if (job == NULL) return;
// First configure widgets
- round_dims = ghb_settings_get_bool(ud->settings, "round_dimensions");
- anamorphic = ghb_settings_get_bool(ud->settings, "anamorphic");
- keep_aspect = ghb_settings_get_bool(ud->settings, "keep_aspect");
- autocrop = ghb_settings_get_bool(ud->settings, "autocrop");
- autoscale = ghb_settings_get_bool(ud->settings, "autoscale");
+ round_dims = ghb_settings_get_boolean(ud->settings, "round_dimensions");
+ anamorphic = ghb_settings_get_boolean(ud->settings, "anamorphic");
+ keep_aspect = ghb_settings_get_boolean(ud->settings, "keep_aspect");
+ autocrop = ghb_settings_get_boolean(ud->settings, "autocrop");
+ autoscale = ghb_settings_get_boolean(ud->settings, "autoscale");
// "Noscale" is a flag that says we prefer to crop extra to satisfy
// alignment constraints rather than scaling to satisfy them.
- noscale = ghb_settings_get_bool(ud->settings, "noscale");
+ noscale = ghb_settings_get_boolean(ud->settings, "noscale");
// Align dimensions to either 16 or 2 pixels
// The scaler crashes if the dimensions are not divisible by 2
// x264 also will not accept dims that are not multiple of 2
@@ -1843,10 +1854,10 @@ ghb_set_scale(signal_user_data_t *ud, gint mode)
crop[2] += need1;
crop[3] += need2;
}
- ghb_ui_update_int (ud, "crop_top", crop[0]);
- ghb_ui_update_int (ud, "crop_bottom", crop[1]);
- ghb_ui_update_int (ud, "crop_left", crop[2]);
- ghb_ui_update_int (ud, "crop_right", crop[3]);
+ ghb_ui_update(ud, "crop_top", ghb_int64_value(crop[0]));
+ ghb_ui_update(ud, "crop_bottom", ghb_int64_value(crop[1]));
+ ghb_ui_update(ud, "crop_left", ghb_int64_value(crop[2]));
+ ghb_ui_update(ud, "crop_right", ghb_int64_value(crop[3]));
}
}
crop[0] = ghb_settings_get_int(ud->settings, "crop_top");
@@ -1959,20 +1970,21 @@ ghb_set_scale(signal_user_data_t *ud, gint mode)
width = ((width + modround) >> modshift) << modshift;
height = ((height + modround) >> modshift) << modshift;
}
- ghb_ui_update_int (ud, "scale_width", width);
- ghb_ui_update_int (ud, "scale_height", height);
+ ghb_ui_update(ud, "scale_width", ghb_int64_value(width));
+ ghb_ui_update(ud, "scale_height", ghb_int64_value(height));
}
static void
-set_preview_job_settings(hb_job_t *job, GHashTable *settings)
+set_preview_job_settings(hb_job_t *job, GValue *settings)
{
job->crop[0] = ghb_settings_get_int(settings, "crop_top");
job->crop[1] = ghb_settings_get_int(settings, "crop_bottom");
job->crop[2] = ghb_settings_get_int(settings, "crop_left");
job->crop[3] = ghb_settings_get_int(settings, "crop_right");
- gboolean anamorphic = ghb_settings_get_bool(settings, "anamorphic");
- gboolean round_dimensions = ghb_settings_get_bool(settings, "round_dimensions");
+ gboolean anamorphic, round_dimensions;
+ anamorphic = ghb_settings_get_boolean(settings, "anamorphic");
+ round_dimensions = ghb_settings_get_boolean(settings, "round_dimensions");
if (round_dimensions && anamorphic)
{
job->modulus = 16;
@@ -1991,12 +2003,12 @@ set_preview_job_settings(hb_job_t *job, GHashTable *settings)
job->width = ghb_settings_get_int(settings, "scale_width");
job->height = ghb_settings_get_int(settings, "scale_height");
gint deint = ghb_settings_get_int(settings, "deinterlace");
- gboolean decomb = ghb_settings_get_bool(settings, "decomb");
+ gboolean decomb = ghb_settings_get_boolean(settings, "decomb");
job->deinterlace = (!decomb && deint == 0) ? 0 : 1;
}
gint
-ghb_calculate_target_bitrate(GHashTable *settings, gint titleindex)
+ghb_calculate_target_bitrate(GValue *settings, gint titleindex)
{
hb_list_t * list;
hb_title_t * title;
@@ -2014,18 +2026,21 @@ ghb_calculate_target_bitrate(GHashTable *settings, gint titleindex)
}
gint
-ghb_guess_bitrate(GHashTable *settings)
+ghb_guess_bitrate(GValue *settings)
{
gint bitrate;
- if (ghb_settings_get_bool(settings, "vquality_type_constant"))
+ if (ghb_settings_get_boolean(settings, "vquality_type_constant"))
{
// This is really rough. I'm trying to err on the high
// side since this is used to estimate if there is
// sufficient disk space left
- gint vcodec = ghb_settings_get_int(settings, "video_codec");
- gdouble vquality = ghb_settings_get_dbl(settings, "video_quality")/100;
+ gint vcodec;
+ gdouble vquality;
+
+ vcodec = ghb_settings_get_int(settings, "video_codec");
+ vquality = ghb_settings_get_double(settings, "video_quality")/100;
if (vcodec == HB_VCODEC_X264 &&
- !ghb_settings_get_bool(settings, "linear_vquality"))
+ !ghb_settings_get_boolean(settings, "linear_vquality"))
{
vquality = 51.0 - vquality * 51.0;
// Convert log curve to linear
@@ -2081,43 +2096,47 @@ gboolean
ghb_validate_filters(signal_user_data_t *ud)
{
gboolean tweaks;
- const gchar *str;
+ gchar *str;
gint index;
gchar *message;
gboolean enabled;
- tweaks = ghb_settings_get_bool(ud->settings, "allow_tweaks");
+ tweaks = ghb_settings_get_boolean(ud->settings, "allow_tweaks");
if (tweaks)
{
// detele 6
str = ghb_settings_get_string(ud->settings, "tweak_detelecine");
- enabled = ghb_settings_get_bool(ud->settings, "detelecine");
+ enabled = ghb_settings_get_boolean(ud->settings, "detelecine");
if (enabled && !ghb_validate_filter_string(str, 6))
{
message = g_strdup_printf(
"Invalid Detelecine Settings:\n\n%s\n",
str);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ g_free(str);
g_free(message);
return FALSE;
}
+ g_free(str);
// decomb 7
str = ghb_settings_get_string(ud->settings, "tweak_decomb");
- enabled = ghb_settings_get_bool(ud->settings, "decomb");
+ enabled = ghb_settings_get_boolean(ud->settings, "decomb");
if (enabled && !ghb_validate_filter_string(str, 7))
{
message = g_strdup_printf(
"Invalid Decomb Settings:\n\n%s\n",
str);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ g_free(str);
g_free(message);
return FALSE;
}
+ g_free(str);
// deinte 4
- index = ghb_settings_get_index(ud->settings, "tweak_deinterlace");
+ index = ghb_settings_get_combo_index(ud->settings, "tweak_deinterlace");
if (index < 0)
{
- str = ghb_settings_get_string(ud->settings, "tweak_deinterlace");
+ str = ghb_settings_get_combo_string(ud->settings, "tweak_deinterlace");
if (!ghb_validate_filter_string(str, 4))
{
message = g_strdup_printf(
@@ -2125,35 +2144,41 @@ ghb_validate_filters(signal_user_data_t *ud)
str);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
g_free(message);
+ g_free(str);
return FALSE;
}
+ g_free(str);
}
// debloc 2
str = ghb_settings_get_string(ud->settings, "tweak_deblock");
- enabled = ghb_settings_get_bool(ud->settings, "deblock");
+ enabled = ghb_settings_get_boolean(ud->settings, "deblock");
if (enabled && !ghb_validate_filter_string(str, 2))
{
message = g_strdup_printf(
"Invalid Deblock Settings:\n\n%s\n",
str);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ g_free(str);
g_free(message);
return FALSE;
}
+ g_free(str);
// denois 4
- index = ghb_settings_get_index(ud->settings, "tweak_denoise");
+ index = ghb_settings_get_combo_index(ud->settings, "tweak_denoise");
if (index < 0)
{
- str = ghb_settings_get_string(ud->settings, "tweak_denoise");
+ str = ghb_settings_get_combo_string(ud->settings, "tweak_denoise");
if (!ghb_validate_filter_string(str, 4))
{
message = g_strdup_printf(
"Invalid Denoise Settings:\n\n%s\n",
str);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ g_free(str);
g_free(message);
return FALSE;
}
+ g_free(str);
}
}
return TRUE;
@@ -2162,12 +2187,11 @@ ghb_validate_filters(signal_user_data_t *ud)
gboolean
ghb_validate_video(signal_user_data_t *ud)
{
- GHashTable *settings = ud->settings;
gint vcodec, mux;
gchar *message;
- mux = ghb_settings_get_int(settings, "container");
- vcodec = ghb_settings_get_int(settings, "video_codec");
+ mux = ghb_settings_get_int(ud->settings, "container");
+ vcodec = ghb_settings_get_int(ud->settings, "video_codec");
if ((mux == HB_MUX_MP4 || mux == HB_MUX_AVI) &&
(vcodec == HB_VCODEC_THEORA))
{
@@ -2183,10 +2207,12 @@ ghb_validate_video(signal_user_data_t *ud)
}
g_free(message);
vcodec = HB_VCODEC_XVID;
- ghb_ui_update_int(ud, "video_codec", vcodec);
+ ghb_ui_update(ud, "video_codec", ghb_int64_value(vcodec));
}
- gboolean decomb = ghb_settings_get_bool(settings, "decomb");
- gboolean vfr = ghb_settings_get_bool(settings, "variable_frame_rate");
+ gboolean decomb;
+ gboolean vfr;
+ decomb = ghb_settings_get_boolean(ud->settings, "decomb");
+ vfr = ghb_settings_get_boolean(ud->settings, "variable_frame_rate");
if (decomb && !vfr)
{
message = g_strdup_printf(
@@ -2195,7 +2221,7 @@ ghb_validate_video(signal_user_data_t *ud)
"Would you like me to enable VFR for you?");
if (ghb_message_dialog(GTK_MESSAGE_WARNING, message, "No", "Yes"))
{
- ghb_ui_update_int(ud, "variable_frame_rate", TRUE);
+ ghb_ui_update(ud, "variable_frame_rate", ghb_boolean_value(TRUE));
}
g_free(message);
}
@@ -2208,12 +2234,15 @@ ghb_validate_container(signal_user_data_t *ud)
gint container;
gchar *message;
- container = ghb_settings_get_bool(ud->settings, "container");
+ container = ghb_settings_get_int(ud->settings, "container");
if (container == HB_MUX_MP4)
{
+ const GValue *audio_list;
gboolean httpopt;
- httpopt = ghb_settings_get_bool(ud->settings, "http_optimize_mp4");
- if (httpopt && ghb_ac3_in_audio_list(ud->audio_settings))
+
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ httpopt = ghb_settings_get_boolean(ud->settings, "http_optimize_mp4");
+ if (httpopt && ghb_ac3_in_audio_list(audio_list))
{
message = g_strdup_printf(
"AC3 audio in HTTP optimized MP4 is not supported.\n\n"
@@ -2225,19 +2254,22 @@ ghb_validate_container(signal_user_data_t *ud)
return FALSE;
}
g_free(message);
- GSList *link = ud->audio_settings;
- while (link != NULL)
+
+ gint count, ii;
+
+ count = ghb_array_len(audio_list);
+ for (ii = 0; ii < count; ii++)
{
- GHashTable *asettings;
- asettings = (GHashTable*)link->data;
+ GValue *asettings;
+
+ asettings = ghb_array_get_nth(audio_list, ii);
gint acodec = ghb_settings_get_int(asettings, "audio_codec");
if (acodec == HB_ACODEC_AC3)
{
- setting_value_t *value;
+ GValue *value;
value = get_acodec_value(HB_ACODEC_FAAC);
- ghb_settings_set(asettings, "audio_codec", value);
+ ghb_settings_take_value(asettings, "audio_codec", value);
}
- link = link->next;
}
}
}
@@ -2249,9 +2281,8 @@ ghb_validate_audio(signal_user_data_t *ud)
{
hb_list_t * list;
hb_title_t * title;
- GHashTable *settings = ud->settings;
gchar *message;
- setting_value_t *value;
+ GValue *value;
if (h == NULL) return FALSE;
list = hb_get_titles( h );
@@ -2262,18 +2293,23 @@ ghb_validate_audio(signal_user_data_t *ud)
return FALSE;
}
- gint titleindex = ghb_settings_get_index(settings, "title");
+ gint titleindex = ghb_settings_get_int(ud->settings, "title");
title = hb_list_item( list, titleindex );
if (title == NULL) return FALSE;
- GSList *link = ud->audio_settings;
- gint mux = ghb_settings_get_int(settings, "container");
- while (link != NULL)
+ gint mux = ghb_settings_get_int(ud->settings, "container");
+
+ const GValue *audio_list;
+ gint count, ii;
+
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ count = ghb_array_len(audio_list);
+ for (ii = 0; ii < count; ii++)
{
- GHashTable *asettings;
+ GValue *asettings;
hb_audio_config_t *taudio;
- asettings = (GHashTable*)link->data;
- gint track = ghb_settings_get_index(asettings, "audio_track");
+ asettings = ghb_array_get_nth(audio_list, ii);
+ gint track = ghb_settings_get_int(asettings, "audio_track");
gint codec = ghb_settings_get_int(asettings, "audio_codec");
taudio = (hb_audio_config_t *) hb_list_audio_config_item( title->list_audio, track );
if ((taudio->in.codec != HB_ACODEC_AC3) && (codec == HB_ACODEC_AC3))
@@ -2298,7 +2334,7 @@ ghb_validate_audio(signal_user_data_t *ud)
codec = HB_ACODEC_FAAC;
}
value = get_acodec_value(codec);
- ghb_settings_set(asettings, "audio_codec", value);
+ ghb_settings_take_value(asettings, "audio_codec", value);
}
gchar *a_unsup = NULL;
gchar *mux_s = NULL;
@@ -2360,7 +2396,7 @@ ghb_validate_audio(signal_user_data_t *ud)
}
g_free(message);
value = get_acodec_value(codec);
- ghb_settings_set(asettings, "audio_codec", value);
+ ghb_settings_take_value(asettings, "audio_codec", value);
}
gint mix = ghb_settings_get_int (asettings, "audio_mix");
gboolean allow_mono = TRUE;
@@ -2420,28 +2456,27 @@ ghb_validate_audio(signal_user_data_t *ud)
g_free(message);
mix = ghb_get_best_mix(titleindex, track, codec, mix);
value = get_amix_value(mix);
- ghb_settings_set(asettings, "audio_mix", value);
+ ghb_settings_take_value(asettings, "audio_mix", value);
}
- link = link->next;
}
return TRUE;
}
gboolean
-ghb_validate_vquality(GHashTable *settings)
+ghb_validate_vquality(GValue *settings)
{
gint vcodec;
gchar *message;
gint min, max;
- if (ghb_settings_get_bool(settings, "nocheckvquality")) return TRUE;
+ if (ghb_settings_get_boolean(settings, "nocheckvquality")) return TRUE;
vcodec = ghb_settings_get_int(settings, "video_codec");
- if (ghb_settings_get_bool(settings, "vquality_type_constant"))
+ if (ghb_settings_get_boolean(settings, "vquality_type_constant"))
{
- if (!ghb_settings_get_bool(settings, "directqp"))
+ if (!ghb_settings_get_boolean(settings, "directqp"))
{
if (vcodec != HB_VCODEC_X264 ||
- ghb_settings_get_bool(settings, "linear_vquality"))
+ ghb_settings_get_boolean(settings, "linear_vquality"))
{
min = 68;
max = 97;
@@ -2470,7 +2505,7 @@ ghb_validate_vquality(GHashTable *settings)
max = 97;
}
}
- gint vquality = ghb_settings_get_dbl(settings, "video_quality");
+ gint vquality = ghb_settings_get_double(settings, "video_quality");
if (vquality < min || vquality > max)
{
message = g_strdup_printf(
@@ -2491,15 +2526,20 @@ ghb_validate_vquality(GHashTable *settings)
}
void
-ghb_add_job(job_settings_t *js, gint unique_id)
+ghb_add_job(GValue *js, gint unique_id)
{
hb_list_t * list;
hb_title_t * title;
hb_job_t * job;
- GHashTable *settings = js->settings;
static gchar *x264opts;
gint sub_id = 0;
gboolean tweaks = FALSE;
+ gchar *detel_str = NULL;
+ gchar *decomb_str = NULL;
+ gchar *deint_str = NULL;
+ gchar *deblock_str = NULL;
+ gchar *denoise_str = NULL;
+ gchar *dest_str = NULL;
g_debug("ghb_add_job()\n");
if (h == NULL) return;
@@ -2511,7 +2551,7 @@ ghb_add_job(job_settings_t *js, gint unique_id)
return;
}
- gint titleindex = ghb_settings_get_index(settings, "title");
+ gint titleindex = ghb_settings_get_int(js, "title");
title = hb_list_item( list, titleindex );
if (title == NULL) return;
@@ -2519,12 +2559,12 @@ ghb_add_job(job_settings_t *js, gint unique_id)
job = title->job;
if (job == NULL) return;
- tweaks = ghb_settings_get_int(settings, "allow_tweaks");
- job->mux = ghb_settings_get_int(settings, "container");
+ tweaks = ghb_settings_get_int(js, "allow_tweaks");
+ job->mux = ghb_settings_get_int(js, "container");
if (job->mux == HB_MUX_MP4)
{
- job->largeFileSize = ghb_settings_get_bool(settings, "large_mp4");
- job->mp4_optimize = ghb_settings_get_bool(settings, "http_optimize_mp4");
+ job->largeFileSize = ghb_settings_get_boolean(js, "large_mp4");
+ job->mp4_optimize = ghb_settings_get_boolean(js, "http_optimize_mp4");
}
else
{
@@ -2532,53 +2572,60 @@ ghb_add_job(job_settings_t *js, gint unique_id)
job->mp4_optimize = FALSE;
}
gint chapter_start, chapter_end;
- chapter_start = ghb_settings_get_int(settings, "start_chapter");
- chapter_end = ghb_settings_get_int(settings, "end_chapter");
+ chapter_start = ghb_settings_get_int(js, "start_chapter");
+ chapter_end = ghb_settings_get_int(js, "end_chapter");
gint num_chapters = hb_list_count(title->list_chapter);
job->chapter_start = MIN( num_chapters, chapter_start );
job->chapter_end = MAX( job->chapter_start, chapter_end );
- job->chapter_markers = ghb_settings_get_bool(settings, "chapter_markers");
+ job->chapter_markers = ghb_settings_get_boolean(js, "chapter_markers");
if ( job->chapter_markers )
{
- gint chapter;
+ GValue *chapters;
+ GValue *chapter;
+ gint chap;
+ gint count;
- for(chapter = chapter_start; chapter <= chapter_end; chapter++)
+ chapters = ghb_settings_get_value(js, "chapter_list");
+ count = ghb_array_len(chapters);
+ for(chap = chapter_start; chap <= chapter_end; chap++)
{
hb_chapter_t * chapter_s;
gchar *name;
- if (js->chapter_list == NULL || js->chapter_list[chapter-1] == 0)
+ name = NULL;
+ if (chap-1 < count)
{
- name = g_strdup_printf ("Chapter %2d", chapter);
+ chapter = ghb_array_get_nth(chapters, chap-1);
+ name = ghb_value_string(chapter);
}
- else
+ if (name == NULL)
{
- name = g_strdup(js->chapter_list[chapter-1]);
+ name = g_strdup_printf ("Chapter %2d", chap);
}
- chapter_s = hb_list_item( job->title->list_chapter, chapter - 1);
+ chapter_s = hb_list_item( job->title->list_chapter, chap - 1);
strncpy(chapter_s->title, name, 1023);
chapter_s->title[1023] = '\0';
g_free(name);
}
}
- job->crop[0] = ghb_settings_get_int(settings, "crop_top");
- job->crop[1] = ghb_settings_get_int(settings, "crop_bottom");
- job->crop[2] = ghb_settings_get_int(settings, "crop_left");
- job->crop[3] = ghb_settings_get_int(settings, "crop_right");
+ job->crop[0] = ghb_settings_get_int(js, "crop_top");
+ job->crop[1] = ghb_settings_get_int(js, "crop_bottom");
+ job->crop[2] = ghb_settings_get_int(js, "crop_left");
+ job->crop[3] = ghb_settings_get_int(js, "crop_right");
- gboolean decomb = ghb_settings_get_bool(settings, "decomb");
+ gboolean decomb = ghb_settings_get_boolean(js, "decomb");
gint deint = ghb_settings_get_int(
- settings, tweaks ? "tweak_deinterlace":"deinterlace");
+ js, tweaks ? "tweak_deinterlace":"deinterlace");
if (!decomb)
job->deinterlace = (deint == 0) ? 0 : 1;
else
job->deinterlace = 0;
- job->grayscale = ghb_settings_get_bool(settings, "grayscale");
+ job->grayscale = ghb_settings_get_boolean(js, "grayscale");
- gboolean anamorphic = ghb_settings_get_bool(settings, "anamorphic");
- gboolean round_dimensions = ghb_settings_get_bool(settings, "round_dimensions");
+ gboolean anamorphic = ghb_settings_get_boolean(js, "anamorphic");
+ gboolean round_dimensions = ghb_settings_get_boolean(js, "round_dimensions");
if (round_dimensions && anamorphic)
{
job->pixel_ratio = 2;
@@ -2598,19 +2645,18 @@ ghb_add_job(job_settings_t *js, gint unique_id)
job->pixel_ratio = 0;
job->modulus = 2;
}
- job->vfr = ghb_settings_get_bool(settings, "variable_frame_rate");
+ job->vfr = ghb_settings_get_boolean(js, "variable_frame_rate");
/* Add selected filters */
job->filters = hb_list_init();
- if( ghb_settings_get_bool(settings, "detelecine" ) || job->vfr )
+ if( ghb_settings_get_boolean(js, "detelecine" ) || job->vfr )
{
hb_filter_detelecine.settings = NULL;
if (tweaks)
{
- const gchar *str;
- str = ghb_settings_get_string(settings, "tweak_detelecine");
- if (str && str[0])
+ detel_str = ghb_settings_get_string(js, "tweak_detelecine");
+ if (detel_str && detel_str[0])
{
- hb_filter_detelecine.settings = (gchar*)str;
+ hb_filter_detelecine.settings = detel_str;
}
}
hb_list_add( job->filters, &hb_filter_detelecine );
@@ -2621,47 +2667,47 @@ ghb_add_job(job_settings_t *js, gint unique_id)
hb_filter_decomb.settings = NULL;
if (tweaks)
{
- const gchar *str;
- str = ghb_settings_get_string(settings, "tweak_decomb");
- if (str && str[0])
+ decomb_str = ghb_settings_get_string(js, "tweak_decomb");
+ if (decomb_str && decomb_str[0])
{
- hb_filter_decomb.settings = (gchar*)str;
+ hb_filter_decomb.settings = (gchar*)decomb_str;
}
}
hb_list_add( job->filters, &hb_filter_decomb );
}
if( job->deinterlace )
{
- hb_filter_deinterlace.settings = (gchar*)ghb_settings_get_string(
- settings, tweaks ? "tweak_deinterlace" : "deinterlace");
+ deint_str = ghb_settings_get_combo_string(js,
+ tweaks ? "tweak_deinterlace" : "deinterlace");
+ hb_filter_deinterlace.settings = deint_str;
hb_list_add( job->filters, &hb_filter_deinterlace );
}
- if( ghb_settings_get_bool(settings, "deblock") )
+ if( ghb_settings_get_boolean(js, "deblock") )
{
hb_filter_deblock.settings = NULL;
if (tweaks)
{
- const gchar *str;
- str = ghb_settings_get_string(settings, "tweak_deblock");
- if (str && str[0])
+ deblock_str = ghb_settings_get_string(js, "tweak_deblock");
+ if (deblock_str && deblock_str[0])
{
- hb_filter_deblock.settings = (gchar*)str;
+ hb_filter_deblock.settings = deblock_str;
}
}
hb_list_add( job->filters, &hb_filter_deblock );
}
gint denoise = ghb_settings_get_int(
- settings, tweaks ? "tweak_denoise" : "denoise");
+ js, tweaks ? "tweak_denoise" : "denoise");
if( denoise != 0 )
{
- hb_filter_denoise.settings = (gchar*)ghb_settings_get_string(
- settings, tweaks ? "tweak_denoise" : "denoise");
- hb_list_add( job->filters, &hb_filter_denoise );
+ denoise_str = (gchar*)ghb_settings_get_combo_string(
+ js, tweaks ? "tweak_denoise" : "denoise");
+ hb_filter_denoise.settings = denoise_str;
+ hb_list_add( job->filters, &hb_filter_deblock );
}
- job->width = ghb_settings_get_int(settings, "scale_width");
- job->height = ghb_settings_get_int(settings, "scale_height");
+ job->width = ghb_settings_get_int(js, "scale_width");
+ job->height = ghb_settings_get_int(js, "scale_height");
- job->vcodec = ghb_settings_get_int(settings, "video_codec");
+ job->vcodec = ghb_settings_get_int(js, "video_codec");
if ((job->mux == HB_MUX_MP4 || job->mux == HB_MUX_AVI) &&
(job->vcodec == HB_VCODEC_THEORA))
{
@@ -2670,15 +2716,16 @@ ghb_add_job(job_settings_t *js, gint unique_id)
}
if ((job->vcodec == HB_VCODEC_X264) && (job->mux == HB_MUX_MP4))
{
- job->ipod_atom = ghb_settings_get_bool(settings, "ipod_file");
+ job->ipod_atom = ghb_settings_get_boolean(js, "ipod_file");
}
- if (ghb_settings_get_bool(settings, "vquality_type_constant"))
+ if (ghb_settings_get_boolean(js, "vquality_type_constant"))
{
- gdouble vquality = ghb_settings_get_dbl(settings, "video_quality");
- if (!ghb_settings_get_bool(settings, "directqp"))
+ gdouble vquality;
+ vquality = ghb_settings_get_double(js, "video_quality");
+ if (!ghb_settings_get_boolean(js, "directqp"))
{
vquality /= 100.0;
- if (ghb_settings_get_bool(settings, "linear_vquality"))
+ if (ghb_settings_get_boolean(js, "linear_vquality"))
{
if (job->vcodec == HB_VCODEC_X264)
{
@@ -2704,10 +2751,10 @@ ghb_add_job(job_settings_t *js, gint unique_id)
job->vquality = vquality;
job->vbitrate = 0;
}
- else if (ghb_settings_get_bool(settings, "vquality_type_bitrate"))
+ else if (ghb_settings_get_boolean(js, "vquality_type_bitrate"))
{
job->vquality = -1.0;
- job->vbitrate = ghb_settings_get_int(settings, "video_bitrate");
+ job->vbitrate = ghb_settings_get_int(js, "video_bitrate");
}
// AVI container does not support variable frame rate.
if (job->mux == HB_MUX_AVI)
@@ -2715,7 +2762,7 @@ ghb_add_job(job_settings_t *js, gint unique_id)
job->vfr = FALSE;
}
- gint vrate = ghb_settings_get_int(settings, "framerate");
+ gint vrate = ghb_settings_get_int(js, "framerate");
if( vrate == 0 || job->vfr )
{
job->vrate = title->rate;
@@ -2737,18 +2784,23 @@ ghb_add_job(job_settings_t *js, gint unique_id)
hb_audio_t *audio = (hb_audio_t*)hb_list_item(job->list_audio, 0);
hb_list_rem(job->list_audio, audio);
}
- GSList *link = js->audio_settings;
- gint count = 0;
- while (link != NULL)
+
+ const GValue *audio_list;
+ gint count;
+ gint tcount = 0;
+
+ audio_list = ghb_settings_get_value(js, "audio_list");
+ count = ghb_array_len(audio_list);
+ for (ii = 0; ii < count; ii++)
{
- GHashTable *asettings;
+ GValue *asettings;
hb_audio_config_t audio;
hb_audio_config_t *taudio;
hb_audio_config_init(&audio);
- asettings = (GHashTable*)link->data;
- audio.in.track = ghb_settings_get_index(asettings, "audio_track");
- audio.out.track = count;
+ asettings = ghb_array_get_nth(audio_list, ii);
+ audio.in.track = ghb_settings_get_int(asettings, "audio_track");
+ audio.out.track = tcount;
audio.out.codec = ghb_settings_get_int(asettings, "audio_codec");
taudio = (hb_audio_config_t *) hb_list_audio_config_item( title->list_audio, audio.in.track );
if ((taudio->in.codec != HB_ACODEC_AC3) && (audio.out.codec == HB_ACODEC_AC3))
@@ -2784,7 +2836,8 @@ ghb_add_job(job_settings_t *js, gint unique_id)
// ogm/faac|ac3 combination is not supported.
audio.out.codec = HB_ACODEC_VORBIS;
}
- audio.out.dynamic_range_compression = ghb_settings_get_dbl(asettings, "audio_drc");
+ audio.out.dynamic_range_compression =
+ ghb_settings_get_double(asettings, "audio_drc");
// It would be better if this were done in libhb for us, but its not yet.
if (audio.out.codec == HB_ACODEC_AC3 || audio.out.codec == HB_ACODEC_DCA)
{
@@ -2806,29 +2859,29 @@ ghb_add_job(job_settings_t *js, gint unique_id)
// Add it to the jobs audio list
hb_audio_add( job, &audio );
- count++;
- link = link->next;
+ tcount++;
}
// I was tempted to move this up with the reset of the video quality
// settings, but I suspect the settings above need to be made
// first in order for hb_calc_bitrate to be accurate.
- if (ghb_settings_get_bool(settings, "vquality_type_target"))
+ if (ghb_settings_get_boolean(js, "vquality_type_target"))
{
gint size;
- size = ghb_settings_get_int(settings, "video_target_size");
+ size = ghb_settings_get_int(js, "video_target_size");
job->vbitrate = hb_calc_bitrate( job, size );
job->vquality = -1.0;
}
- job->file = ghb_settings_get_string(settings, "destination");
- job->crf = ghb_settings_get_bool(settings, "constant_rate_factor");
+ dest_str = ghb_settings_get_string(js, "destination");
+ job->file = dest_str;
+ job->crf = ghb_settings_get_boolean(js, "constant_rate_factor");
// TODO: libhb holds onto a reference to the x264opts and is not
// finished with it until encoding the job is done. But I can't
// find a way to get at the job before it is removed in order to
// free up the memory I am allocating here.
// The short story is THIS LEAKS.
- x264opts = ghb_build_x264opts_string(settings);
+ x264opts = ghb_build_x264opts_string(js);
if( x264opts != NULL && *x264opts != '\0' )
{
@@ -2838,8 +2891,8 @@ ghb_add_job(job_settings_t *js, gint unique_id)
{
job->x264opts = NULL;
}
- gint subtitle = ghb_settings_get_int(settings, "subtitle_lang");
- gboolean forced_subtitles = ghb_settings_get_bool (settings, "forced_subtitles");
+ gint subtitle = ghb_settings_get_int(js, "subtitle_lang");
+ gboolean forced_subtitles = ghb_settings_get_boolean(js, "forced_subtitles");
job->subtitle_force = forced_subtitles;
if (subtitle >= 0)
job->subtitle = subtitle;
@@ -2877,8 +2930,8 @@ ghb_add_job(job_settings_t *js, gint unique_id)
{
job->select_subtitle = NULL;
}
- if( ghb_settings_get_bool(settings, "two_pass") &&
- !ghb_settings_get_bool(settings, "vquality_type_constant"))
+ if( ghb_settings_get_boolean(js, "two_pass") &&
+ !ghb_settings_get_boolean(js, "vquality_type_constant"))
{
/*
* If subtitle_scan is enabled then only turn it on
@@ -2898,7 +2951,7 @@ ghb_add_job(job_settings_t *js, gint unique_id)
* If turbo options have been selected then append them
* to the x264opts now (size includes one ':' and the '\0')
*/
- if( ghb_settings_get_bool(settings, "turbo") )
+ if( ghb_settings_get_boolean(js, "turbo") )
{
char *tmp_x264opts;
@@ -2948,6 +3001,12 @@ ghb_add_job(job_settings_t *js, gint unique_id)
//if (job->x264opts != NULL)
// g_free(job->x264opts);
}
+ if (detel_str) g_free(detel_str);
+ if (decomb_str) g_free(decomb_str);
+ if (deint_str) g_free(deint_str);
+ if (deblock_str) g_free(deblock_str);
+ if (denoise_str) g_free(denoise_str);
+ if (dest_str) g_free(dest_str);
}
void
@@ -2996,7 +3055,11 @@ ghb_pause_queue()
}
GdkPixbuf*
-ghb_get_preview_image(gint titleindex, gint index, GHashTable *settings, gboolean borders)
+ghb_get_preview_image(
+ gint titleindex,
+ gint index,
+ GValue *settings,
+ gboolean borders)
{
hb_title_t *title;
hb_list_t *list;
@@ -3118,7 +3181,7 @@ ghb_get_preview_image(gint titleindex, gint index, GHashTable *settings, gboolea
// Got it, but hb_get_preview doesn't compensate for anamorphic, so lets
// scale
gint width, height, par_width, par_height;
- gboolean anamorphic = ghb_settings_get_bool (settings, "anamorphic");
+ gboolean anamorphic = ghb_settings_get_boolean(settings, "anamorphic");
if (anamorphic)
{
hb_set_anamorphic_size( title->job, &width, &height, &par_width, &par_height );
diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h
index eaf4e4c56..3e171f1cf 100644
--- a/gtk/src/hb-backend.h
+++ b/gtk/src/hb-backend.h
@@ -78,53 +78,58 @@ typedef struct
#define GHB_AUDIO_BITRATE 2
#define GHB_FRAMERATE 3
-const gchar* ghb_version();
+const gchar* ghb_version(void);
void ghb_vquality_range(signal_user_data_t *ud, gint *min, gint *max);
//const gchar* ghb_get_rate_string(gint rate, gint type);
void ghb_backend_init(GtkBuilder *builder, gint debug, gint update);
-void ghb_add_job(job_settings_t *js, gint unique_id);
+void ghb_add_job(GValue *js, gint unique_id);
void ghb_remove_job(gint unique_id);
-void ghb_start_queue();
-void ghb_stop_queue();
-void ghb_pause_queue();
+void ghb_start_queue(void);
+void ghb_stop_queue(void);
+void ghb_pause_queue(void);
-gint ghb_get_state();
+gint ghb_get_state(void);
void ghb_clear_state(gint state);
void ghb_set_state(gint state);
void ghb_get_status(ghb_status_t *status);
-void ghb_track_status();
+void ghb_track_status(void);
void ghb_backend_scan(const gchar *path, gint titleindex);
gboolean ghb_get_title_info(ghb_title_info_t *tinfo, gint titleindex);
void ghb_set_scale(signal_user_data_t *ud, gint mode);
-gchar ** ghb_get_chapters(gint titleindex);
+GValue* ghb_get_chapters(gint titleindex);
gint ghb_get_best_mix(gint titleindex, gint track, gint acodec, gint mix);
-gboolean ghb_ac3_in_audio_list(GSList *audio_list);
+gboolean ghb_ac3_in_audio_list(const GValue *audio_list);
gboolean ghb_audio_is_passthru(gint acodec);
-gint ghb_get_default_acodec();
-gboolean ghb_get_audio_info(ghb_audio_info_t *ainfo, gint titleindex, gint audioindex);
+gint ghb_get_default_acodec(void);
+gboolean ghb_get_audio_info(
+ ghb_audio_info_t *ainfo, gint titleindex, gint audioindex);
gboolean ghb_set_passthru_rate_opts(GtkBuilder *builder, gint bitrate);
gboolean ghb_set_default_rate_opts(GtkBuilder *builder);
void ghb_grey_combo_options(GtkBuilder *builder);
-void ghb_update_ui_combo_box(GtkBuilder *builder, const gchar *name, gint user_data, gboolean all);
+void ghb_update_ui_combo_box(
+ GtkBuilder *builder, const gchar *name, gint user_data, gboolean all);
gint ghb_find_audio_track(gint titleindex, const gchar *lang, gint index);
-gint ghb_longest_title();
-gchar* ghb_build_x264opts_string(GHashTable *settings);
-GdkPixbuf* ghb_get_preview_image(gint titleindex, gint index, GHashTable *settings, gboolean borders);
-gint ghb_calculate_target_bitrate(GHashTable *settings, gint titleindex);
+gint ghb_longest_title(void);
+gchar* ghb_build_x264opts_string(GValue *settings);
+GdkPixbuf* ghb_get_preview_image(
+ gint titleindex, gint index, GValue *settings, gboolean borders);
+gint ghb_calculate_target_bitrate(GValue *settings, gint titleindex);
gchar* ghb_dvd_volname(const gchar *device);
-gint ghb_guess_bitrate(GHashTable *settings);
+gint ghb_guess_bitrate(GValue *settings);
gboolean ghb_validate_container(signal_user_data_t *ud);
-gboolean ghb_validate_vquality(GHashTable *settings);
+gboolean ghb_validate_vquality(GValue *settings);
gboolean ghb_validate_audio(signal_user_data_t *ud);
gboolean ghb_validate_video(signal_user_data_t *ud);
gboolean ghb_validate_filters(signal_user_data_t *ud);
gboolean ghb_validate_filter_string(const gchar *str, gint max_fields);
void ghb_hb_cleanup(gboolean partial);
-gint ghb_lookup_acodec(const gchar *acodec);
+gint ghb_lookup_acodec(const GValue *acodec);
+gint ghb_lookup_mix(const GValue *mix);
+#if 0
gint ghb_lookup_bitrate(const gchar *bitrate);
gint ghb_lookup_rate(const gchar *rate);
-gint ghb_lookup_mix(const gchar *mix);
gdouble ghb_lookup_drc(const gchar *drc);
+#endif
#endif // _HBBACKEND_H_
diff --git a/gtk/src/ini_to_plist.c b/gtk/src/ini_to_plist.c
new file mode 100644
index 000000000..d0d441d8d
--- /dev/null
+++ b/gtk/src/ini_to_plist.c
@@ -0,0 +1,104 @@
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <string.h>
+#include "values.h"
+#include "plist.h"
+
+gboolean
+string_is_true(const gchar *str)
+{
+ return (strcmp(str, "enable") == 0);
+}
+
+gboolean
+string_is_bool(const gchar *str)
+{
+ return (strcmp(str, "enable") == 0) || (strcmp(str, "disable") == 0);
+}
+
+GType
+guess_type(const gchar *str)
+{
+ gchar *end;
+ gdouble dval;
+
+ if (*str == 0)
+ return G_TYPE_STRING;
+ if (string_is_bool(str))
+ return G_TYPE_BOOLEAN;
+ dval = g_strtod(str, &end);
+ if (*end == 0)
+ {
+ if (strchr(str, '.') == NULL)
+ return G_TYPE_INT64;
+ else
+ return G_TYPE_DOUBLE;
+ }
+
+ return G_TYPE_STRING;
+}
+
+void
+set_value(GValue *gval, const gchar *str, GType gtype)
+{
+ if (gtype == G_TYPE_STRING)
+ {
+ g_value_set_string(gval, str);
+ }
+ else if (gtype == G_TYPE_INT64)
+ {
+ gint64 val = g_strtod(str, NULL);
+ g_value_set_int64(gval, val);
+ }
+ else if (gtype == G_TYPE_DOUBLE)
+ {
+ gdouble val = g_strtod(str, NULL);
+ g_value_set_double(gval, val);
+ }
+ else if (gtype == G_TYPE_BOOLEAN)
+ {
+ if (string_is_true(str))
+ g_value_set_boolean(gval, TRUE);
+ else
+ g_value_set_boolean(gval, FALSE);
+ }
+}
+
+int
+main(gint argc, gchar *argv[])
+{
+ GKeyFile *kf;
+ gchar **groups;
+ gchar **keys;
+ gint ii, jj;
+ GValue *top;
+ GValue *dict;
+
+ g_type_init();
+ top = ghb_dict_value_new();
+ kf = g_key_file_new();
+ g_key_file_load_from_file(kf, argv[1], 0, NULL);
+ groups = g_key_file_get_groups(kf, NULL);
+ for (ii = 0; groups[ii]; ii++)
+ {
+ dict = ghb_dict_value_new();
+ ghb_dict_insert(top, , g_strdup(groups[ii]), dict);
+ keys = g_key_file_get_keys(kf, groups[ii], NULL, NULL);
+ for (jj = 0; keys[jj]; jj++)
+ {
+ gchar *str;
+ GValue *gval;
+ GType gtype;
+
+ str = g_key_file_get_string(kf, groups[ii], keys[jj], NULL);
+ gtype = guess_type(str);
+ gval = g_malloc0(sizeof(GValue));
+ g_value_init(gval, gtype);
+ set_value(gval, str, gtype);
+ ghb_dict_insert(dict, g_strdup(keys[jj]), gval);
+ }
+ }
+ ghb_plist_write_file("a_p_list", top);
+}
+
diff --git a/gtk/src/internal_defaults.h b/gtk/src/internal_defaults.h
index 7751dd2e5..fe4e9317f 100644
--- a/gtk/src/internal_defaults.h
+++ b/gtk/src/internal_defaults.h
@@ -1,90 +1,197 @@
-"[Presets]\n"
-"preset_type=1\n"
-"preset_description=\n"
-"subtitle_lang=none\n"
-"forced_subtitles=enable\n"
-"source_audio_lang=und\n"
-"pref_audio_codec=ac3\n"
-"pref_audio_bitrate=192\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1.0\n"
-"chapter_markers=enable\n"
-"container=mp4\n"
-"ipod_file=disable\n"
-"large_mp4=disable\n"
-"autocrop=enable\n"
-"autoscale=enable\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=enable\n"
-"round_dimensions=enable\n"
-"keep_aspect=enable\n"
-"detelecine=enable\n"
-"decomb=enable\n"
-"deinterlace=none\n"
-"denoise=none\n"
-"deblock=disable\n"
-"tweak_decomb=\n"
-"tweak_detelecine=\n"
-"tweak_deblock=\n"
-"grayscale=disable\n"
-"video_codec=x264\n"
-"two_pass=disable\n"
-"turbo=enable\n"
-"constant_rate_factor=enable\n"
-"variable_frame_rate=enable\n"
-"framerate=source\n"
-"vquality_type_constant=disable\n"
-"vquality_type_bitrate=disable\n"
-"vquality_type_target=disable\n"
-"video_bitrate=1800\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=\n"
-"directqp=disable\n"
-"\n"
-"[Initialization]\n"
-"title=none\n"
-"start_chapter=1\n"
-"end_chapter=100\n"
-"scale_width=720\n"
-"scale_height=480\n"
-"crop_top=0\n"
-"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"
-"default_preset=Normal\n"
-"default_source=/dev/dvd\n"
-"destination_dir=\n"
-"use_source_name=enable\n"
-"hbfd=disable\n"
-"hbfd_feature=disable\n"
-"show_presets=enable\n"
-"linear_vquality=disable\n"
-"noscale=disable\n"
-"nocheckvquality=disable\n"
-"allow_tweaks=disable\n"
-"\n"
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+"<plist version=\"1.0\">\n"
+"<dict>\n"
+" <key>Initialization</key>\n"
+" <dict>\n"
+" <key>crop_bottom</key>\n"
+" <integer>0</integer>\n"
+" <key>crop_left</key>\n"
+" <integer>0</integer>\n"
+" <key>crop_right</key>\n"
+" <integer>0</integer>\n"
+" <key>crop_top</key>\n"
+" <integer>0</integer>\n"
+" <key>end_chapter</key>\n"
+" <integer>100</integer>\n"
+" <key>preset</key>\n"
+" <string>Normal</string>\n"
+" <key>scale_height</key>\n"
+" <integer>480</integer>\n"
+" <key>scale_width</key>\n"
+" <integer>720</integer>\n"
+" <key>start_chapter</key>\n"
+" <integer>1</integer>\n"
+" <key>title</key>\n"
+" <string>none</string>\n"
+" <key>volume_label</key>\n"
+" <string>New Video</string>\n"
+" <key>x264_8x8dct</key>\n"
+" <false />\n"
+" <key>x264_analyse</key>\n"
+" <string>some</string>\n"
+" <key>x264_bframes</key>\n"
+" <integer>0</integer>\n"
+" <key>x264_bime</key>\n"
+" <false />\n"
+" <key>x264_bpyramid</key>\n"
+" <false />\n"
+" <key>x264_brdo</key>\n"
+" <false />\n"
+" <key>x264_cabac</key>\n"
+" <true />\n"
+" <key>x264_deblock_alpha</key>\n"
+" <integer>0</integer>\n"
+" <key>x264_deblock_beta</key>\n"
+" <integer>0</integer>\n"
+" <key>x264_direct</key>\n"
+" <string>spatial</string>\n"
+" <key>x264_me</key>\n"
+" <string>hex</string>\n"
+" <key>x264_merange</key>\n"
+" <integer>16</integer>\n"
+" <key>x264_mixed_refs</key>\n"
+" <false />\n"
+" <key>x264_no_dct_decimate</key>\n"
+" <false />\n"
+" <key>x264_no_fast_pskip</key>\n"
+" <false />\n"
+" <key>x264_refs</key>\n"
+" <integer>1</integer>\n"
+" <key>x264_subme</key>\n"
+" <integer>5</integer>\n"
+" <key>x264_trellis</key>\n"
+" <integer>0</integer>\n"
+" <key>x264_weighted_bframes</key>\n"
+" <false />\n"
+" <key>audio_list</key>\n"
+" <array>\n"
+" </array>\n"
+" </dict>\n"
+" <key>Preferences</key>\n"
+" <dict>\n"
+" <key>allow_tweaks</key>\n"
+" <false />\n"
+" <key>default_preset</key>\n"
+" <string>Normal</string>\n"
+" <key>default_source</key>\n"
+" <string>/dev/dvd</string>\n"
+" <key>destination_dir</key>\n"
+" <string></string>\n"
+" <key>hbfd</key>\n"
+" <false />\n"
+" <key>hbfd_feature</key>\n"
+" <false />\n"
+" <key>linear_vquality</key>\n"
+" <false />\n"
+" <key>nocheckvquality</key>\n"
+" <false />\n"
+" <key>noscale</key>\n"
+" <false />\n"
+" <key>show_presets</key>\n"
+" <true />\n"
+" <key>use_source_name</key>\n"
+" <true />\n"
+" <key>version</key>\n"
+" <string>0.1</string>\n"
+" </dict>\n"
+" <key>Presets</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>constant_rate_factor</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <true />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <string>none</string>\n"
+" <key>detelecine</key>\n"
+" <true />\n"
+" <key>directqp</key>\n"
+" <false />\n"
+" <key>forced_subtitles</key>\n"
+" <true />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>http_optimize_mp4</key>\n"
+" <false />\n"
+" <key>ipod_file</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>large_mp4</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>192</string>\n"
+" <key>audio_codec</key>\n"
+" <string>ac3</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string></string>\n"
+" <key>preset_type</key>\n"
+" <integer>1</integer>\n"
+" <key>round_dimensions</key>\n"
+" <true />\n"
+" <key>source_audio_lang</key>\n"
+" <string>und</string>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <false />\n"
+" <key>tweak_deblock</key>\n"
+" <string></string>\n"
+" <key>tweak_decomb</key>\n"
+" <string></string>\n"
+" <key>tweak_detelecine</key>\n"
+" <string></string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <true />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1800</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <false />\n"
+" <key>vquality_type_constant</key>\n"
+" <false />\n"
+" <key>vquality_type_target</key>\n"
+" <false />\n"
+" <key>x264_options</key>\n"
+" <string></string>\n"
+" </dict>\n"
+"</dict>\n"
+"</plist>\n"
diff --git a/gtk/src/internal_defaults.xml b/gtk/src/internal_defaults.xml
new file mode 100644
index 000000000..94c5012bb
--- /dev/null
+++ b/gtk/src/internal_defaults.xml
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Initialization</key>
+ <dict>
+ <key>crop_bottom</key>
+ <integer>0</integer>
+ <key>crop_left</key>
+ <integer>0</integer>
+ <key>crop_right</key>
+ <integer>0</integer>
+ <key>crop_top</key>
+ <integer>0</integer>
+ <key>end_chapter</key>
+ <integer>100</integer>
+ <key>preset</key>
+ <string>Normal</string>
+ <key>scale_height</key>
+ <integer>480</integer>
+ <key>scale_width</key>
+ <integer>720</integer>
+ <key>start_chapter</key>
+ <integer>1</integer>
+ <key>title</key>
+ <string>none</string>
+ <key>volume_label</key>
+ <string>New Video</string>
+ <key>x264_8x8dct</key>
+ <false />
+ <key>x264_analyse</key>
+ <string>some</string>
+ <key>x264_bframes</key>
+ <integer>0</integer>
+ <key>x264_bime</key>
+ <false />
+ <key>x264_bpyramid</key>
+ <false />
+ <key>x264_brdo</key>
+ <false />
+ <key>x264_cabac</key>
+ <true />
+ <key>x264_deblock_alpha</key>
+ <integer>0</integer>
+ <key>x264_deblock_beta</key>
+ <integer>0</integer>
+ <key>x264_direct</key>
+ <string>spatial</string>
+ <key>x264_me</key>
+ <string>hex</string>
+ <key>x264_merange</key>
+ <integer>16</integer>
+ <key>x264_mixed_refs</key>
+ <false />
+ <key>x264_no_dct_decimate</key>
+ <false />
+ <key>x264_no_fast_pskip</key>
+ <false />
+ <key>x264_refs</key>
+ <integer>1</integer>
+ <key>x264_subme</key>
+ <integer>5</integer>
+ <key>x264_trellis</key>
+ <integer>0</integer>
+ <key>x264_weighted_bframes</key>
+ <false />
+ <key>audio_list</key>
+ <array>
+ </array>
+ </dict>
+ <key>Preferences</key>
+ <dict>
+ <key>allow_tweaks</key>
+ <false />
+ <key>default_preset</key>
+ <string>Normal</string>
+ <key>default_source</key>
+ <string>/dev/dvd</string>
+ <key>destination_dir</key>
+ <string></string>
+ <key>hbfd</key>
+ <false />
+ <key>hbfd_feature</key>
+ <false />
+ <key>linear_vquality</key>
+ <false />
+ <key>nocheckvquality</key>
+ <false />
+ <key>noscale</key>
+ <false />
+ <key>show_presets</key>
+ <true />
+ <key>use_source_name</key>
+ <true />
+ <key>version</key>
+ <string>0.1</string>
+ </dict>
+ <key>Presets</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>constant_rate_factor</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <true />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <string>none</string>
+ <key>detelecine</key>
+ <true />
+ <key>directqp</key>
+ <false />
+ <key>forced_subtitles</key>
+ <true />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>http_optimize_mp4</key>
+ <false />
+ <key>ipod_file</key>
+ <false />
+ <key>keep_aspect</key>
+ <true />
+ <key>large_mp4</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>192</string>
+ <key>audio_codec</key>
+ <string>ac3</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string></string>
+ <key>preset_type</key>
+ <integer>1</integer>
+ <key>round_dimensions</key>
+ <true />
+ <key>source_audio_lang</key>
+ <string>und</string>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <false />
+ <key>tweak_deblock</key>
+ <string></string>
+ <key>tweak_decomb</key>
+ <string></string>
+ <key>tweak_detelecine</key>
+ <string></string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <true />
+ <key>video_bitrate</key>
+ <integer>1800</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <false />
+ <key>vquality_type_constant</key>
+ <false />
+ <key>vquality_type_target</key>
+ <false />
+ <key>x264_options</key>
+ <string></string>
+ </dict>
+</dict>
+</plist>
diff --git a/gtk/src/main.c b/gtk/src/main.c
index 3c4039cff..cc5c20a2e 100644
--- a/gtk/src/main.c
+++ b/gtk/src/main.c
@@ -66,6 +66,7 @@
#include "callbacks.h"
#include "settings.h"
+#include "presets.h"
#define BUILDER_NAME "ghb"
@@ -316,14 +317,14 @@ bind_audio_tree_model (signal_user_data_t *ud)
g_debug("bind_audio_tree_model ()\n");
treeview = GTK_TREE_VIEW(GHB_WIDGET (ud->builder, "audio_list"));
selection = gtk_tree_view_get_selection (treeview);
- // 11 columns in model. 6 are visible, the other 5 are for storing
+ // 12 columns in model. 6 are visible, the other 6 are for storing
// values that I need
- treestore = gtk_list_store_new(11, G_TYPE_STRING, G_TYPE_STRING,
+ treestore = gtk_list_store_new(12, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_STRING);
+ G_TYPE_STRING, G_TYPE_DOUBLE);
gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(treestore));
cell = gtk_cell_renderer_text_new();
@@ -472,7 +473,7 @@ main (int argc, char *argv[])
{
GtkWidget *window;
signal_user_data_t *ud;
- const gchar *preset;
+ gchar *preset;
gchar *builder_file;
GError *error = NULL;
GOptionContext *context;
@@ -505,8 +506,6 @@ main (int argc, char *argv[])
ud->debug = FALSE;
g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, debug_log_handler, ud);
ud->settings = ghb_settings_new();
- ud->audio_settings = NULL;
- ud->chapter_list = NULL;
ud->queue = NULL;
ud->current_dvd_device = NULL;
// Redirect stderr to the activity window
@@ -519,6 +518,7 @@ main (int argc, char *argv[])
ud->builder = create_builder_or_die (BUILDER_NAME, builder_file);
g_free(builder_file);
}
+ ghb_init_dep_map();
// Need to connect x264_options textview buffer to the changed signal
// since it can't be done automatically
@@ -533,6 +533,7 @@ main (int argc, char *argv[])
g_debug("ud %p\n", ud);
g_debug("ud->builder %p\n", ud->builder);
+
bind_audio_tree_model(ud);
bind_presets_tree_model(ud);
bind_queue_tree_model(ud);
@@ -542,13 +543,23 @@ main (int argc, char *argv[])
// to the callbacks. Builder's standard autoconnect doesn't all this.
gtk_builder_connect_signals_full (ud->builder, MyConnect, ud);
+ // Load all internal settings
+ ghb_settings_init(ud);
+ // Load the presets files
+ ghb_presets_load();
ghb_prefs_load(ud);
- if (ghb_settings_get_bool(ud->settings, "hbfd"))
+
+ // Start the show.
+ window = GHB_WIDGET (ud->builder, "hb_window");
+ gtk_widget_show (window);
+
+ ghb_prefs_to_ui(ud);
+
+ if (ghb_settings_get_boolean(ud->settings, "hbfd"))
{
ghb_hbfd(ud, TRUE);
}
- const gchar *source = ghb_settings_get_string(ud->settings, "default_source");
- gboolean tweaks = ghb_settings_get_bool(ud->settings, "allow_tweaks");
+ gboolean tweaks = ghb_settings_get_boolean(ud->settings, "allow_tweaks");
GtkWidget *widget;
widget = GHB_WIDGET(ud->builder, "deinterlace");
tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
@@ -560,30 +571,27 @@ main (int argc, char *argv[])
widget = GHB_WIDGET(ud->builder, "tweak_denoise");
!tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
+ gchar *source = ghb_settings_get_string(ud->settings, "default_source");
ghb_dvd_set_current(source, ud);
- // Start the show.
- window = GHB_WIDGET (ud->builder, "hb_window");
- gtk_widget_show (window);
+ g_free(source);
+
+ // Parsing x264 options "" initializes x264 widgets to proper defaults
+ ghb_x264_parse_options(ud, "");
- // Load the presets files
- ghb_presets_load(ud);
// Populate the presets tree view
ghb_presets_list_update(ud);
// Get the first preset name
if (arg_preset != NULL)
{
- preset = arg_preset;
+ ghb_select_preset(ud->builder, arg_preset);
}
else
{
preset = ghb_settings_get_string (ud->settings, "default_preset");
- if (preset == NULL)
- preset = ghb_presets_get_name(0);
+ ghb_select_preset(ud->builder, preset);
+ g_free(preset);
}
- // 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
ghb_check_all_depencencies (ud);
diff --git a/gtk/src/makedeps.c b/gtk/src/makedeps.c
new file mode 100644
index 000000000..8637ccc2e
--- /dev/null
+++ b/gtk/src/makedeps.c
@@ -0,0 +1,136 @@
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <string.h>
+#include "values.h"
+#include "plist.h"
+
+typedef struct
+{
+ const gchar *widget_name;
+ const gchar *dep_name;
+ const gchar *enable_value;
+ const gboolean disable_if_equal;
+} dependency_t;
+
+static dependency_t dep_map[] =
+{
+ {"title", "queue_add", "none", TRUE},
+ {"title", "queue_add_menu", "none", TRUE},
+ {"title", "preview_button", "none", TRUE},
+ {"title", "show_preview_menu", "none", TRUE},
+ {"title", "preview_frame", "none", TRUE},
+ {"title", "picture_label", "none", TRUE},
+ {"title", "picture_tab", "none", TRUE},
+ {"title", "chapters_label", "none", TRUE},
+ {"title", "chapters_tab", "none", TRUE},
+ {"title", "title", "none", TRUE},
+ {"title", "start_chapter", "none", TRUE},
+ {"title", "end_chapter", "none", TRUE},
+ {"vquality_type_bitrate", "video_bitrate", "TRUE", FALSE},
+ {"vquality_type_target", "video_target_size", "TRUE", FALSE},
+ {"vquality_type_constant", "video_quality", "TRUE", FALSE},
+ {"vquality_type_constant", "constant_rate_factor", "TRUE", FALSE},
+ {"vquality_type_constant", "two_pass", "TRUE", TRUE},
+ {"vquality_type_constant", "turbo", "TRUE", TRUE},
+ {"two_pass", "turbo", "TRUE", FALSE},
+ {"container", "large_mp4", "mp4|m4v", FALSE},
+ {"container", "http_optimize_mp4", "mp4|m4v", FALSE},
+ {"container", "ipod_file", "mp4|m4v", FALSE},
+ {"container", "variable_frame_rate", "avi", TRUE},
+ {"variable_frame_rate", "framerate", "TRUE", TRUE},
+ {"variable_frame_rate", "detelecine", "TRUE", TRUE},
+ {"decomb", "deinterlace", "TRUE", TRUE},
+ {"decomb", "tweak_deinterlace", "TRUE", TRUE},
+ {"autocrop", "crop_top", "FALSE", FALSE},
+ {"autocrop", "crop_bottom", "FALSE", FALSE},
+ {"autocrop", "crop_left", "FALSE", FALSE},
+ {"autocrop", "crop_right", "FALSE", FALSE},
+ {"autoscale", "scale_width", "FALSE", FALSE},
+ {"autoscale", "scale_height", "FALSE", FALSE},
+ {"anamorphic", "keep_aspect", "FALSE", FALSE},
+ {"anamorphic", "scale_height", "FALSE", FALSE},
+ {"keep_aspect", "scale_height", "FALSE", FALSE},
+ {"video_codec", "x264_tab", "x264", FALSE},
+ {"video_codec", "x264_tab_label", "x264", FALSE},
+ {"video_codec", "ipod_file", "x264", FALSE},
+ {"audio_codec", "audio_bitrate", "ac3", TRUE},
+ {"audio_codec", "audio_rate", "ac3", TRUE},
+ {"audio_codec", "audio_mix", "ac3", TRUE},
+ {"audio_codec", "audio_drc", "ac3", TRUE},
+ {"x264_bframes", "x264_weighted_bframes", "0", TRUE},
+ {"x264_bframes", "x264_brdo", "0", TRUE},
+ {"x264_bframes", "x264_bime", "0", TRUE},
+ {"x264_bframes", "x264_bpyramid", "<2", TRUE},
+ {"x264_bframes", "x264_direct", "0", TRUE},
+ {"x264_refs", "x264_mixed_refs", "<2", TRUE},
+ {"x264_cabac", "x264_trellis", "TRUE", FALSE},
+ {"x264_subme", "x264_brdo", "<6", TRUE},
+ {"x264_analyse", "x264_direct", "none", TRUE},
+ {"x264_me", "x264_merange", "umh|esa", FALSE},
+ {"chapter_markers", "chapters_list", "TRUE", FALSE},
+};
+
+int
+main(gint argc, gchar *argv[])
+{
+ gint ii, jj;
+ GValue *top;
+ gint count = sizeof(dep_map) / sizeof(dependency_t);
+
+ g_type_init();
+
+ top = ghb_dict_value_new();
+ for (ii = 0; ii < count; ii++)
+ {
+ const gchar *name;
+ GValue *array;
+
+ name = dep_map[ii].widget_name;
+ if (ghb_dict_lookup(top, name))
+ continue;
+ array = ghb_array_value_new(8);
+ for (jj = 0; jj < count; jj++)
+ {
+ if (strcmp(name, dep_map[jj].widget_name) == 0)
+ {
+ ghb_array_append(array,
+ ghb_value_dup(ghb_string_value(dep_map[jj].dep_name)));
+ }
+ }
+ ghb_dict_insert(top, g_strdup(name), array);
+ }
+ ghb_plist_write_file("widget_deps", top);
+
+ // reverse map
+ top = ghb_dict_value_new();
+ for (ii = 0; ii < count; ii++)
+ {
+ const gchar *name;
+ GValue *array;
+
+ name = dep_map[ii].dep_name;
+ if (ghb_dict_lookup(top, name))
+ continue;
+ array = ghb_array_value_new(8);
+ for (jj = 0; jj < count; jj++)
+ {
+ if (strcmp(name, dep_map[jj].dep_name) == 0)
+ {
+ GValue *data;
+ data = ghb_array_value_new(3);
+ ghb_array_append(data, ghb_value_dup(
+ ghb_string_value(dep_map[jj].widget_name)));
+ ghb_array_append(data, ghb_value_dup(
+ ghb_string_value(dep_map[jj].enable_value)));
+ ghb_array_append(data, ghb_value_dup(
+ ghb_boolean_value(dep_map[jj].disable_if_equal)));
+ ghb_array_append(array, data);
+ }
+ }
+ ghb_dict_insert(top, g_strdup(name), array);
+ }
+ ghb_plist_write_file("widget_reverse_deps", top);
+ return 0;
+}
+
diff --git a/gtk/src/plist.c b/gtk/src/plist.c
new file mode 100644
index 000000000..da7bc55e7
--- /dev/null
+++ b/gtk/src/plist.c
@@ -0,0 +1,587 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#include "plist.h"
+#include "values.h"
+
+#define BUF_SZ (128*1024)
+
+static gchar *preamble =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+ "<plist version=\"1.0\">\n";
+static gchar *postfix =
+ "</plist>\n";
+
+enum
+{
+ P_NONE = 0,
+ P_PLIST,
+ P_KEY,
+ P_ARRAY,
+ P_DICT,
+ P_INTEGER,
+ P_REAL,
+ P_STRING,
+ P_DATE,
+ P_TRUE,
+ P_FALSE,
+ P_DATA,
+};
+
+typedef struct
+{
+ gchar *tag;
+ gint id;
+} tag_map_t;
+
+static tag_map_t tag_map[] =
+{
+ {"plist", P_PLIST},
+ {"key", P_KEY},
+ {"array", P_ARRAY},
+ {"dict", P_DICT},
+ {"integer", P_INTEGER},
+ {"real", P_REAL},
+ {"string", P_STRING},
+ {"date", P_DATE},
+ {"true", P_TRUE},
+ {"false", P_FALSE},
+ {"data", P_DATA},
+};
+#define TAG_MAP_SZ (sizeof(tag_map)/sizeof(tag_map_t))
+
+typedef struct
+{
+ gchar *key;
+ gchar *value;
+ GValue *plist;
+ GQueue *stack;
+ GQueue *tag_stack;
+ gboolean closed_top;
+} parse_data_t;
+
+static void
+start_element(
+ GMarkupParseContext *ctx,
+ const gchar *name,
+ const gchar **attr_names,
+ const gchar **attr_values,
+ gpointer ud,
+ GError **error)
+{
+ parse_data_t *pd = (parse_data_t*)ud;
+ union
+ {
+ gint id;
+ gpointer pid;
+ } id;
+ gint ii;
+
+ // Check to see if the first element found has been closed
+ // If so, ignore any junk following it.
+ if (pd->closed_top)
+ return;
+
+ for (ii = 0; ii < TAG_MAP_SZ; ii++)
+ {
+ if (strcmp(name, tag_map[ii].tag) == 0)
+ {
+ id.id = tag_map[ii].id;
+ break;
+ }
+ }
+ if (ii == TAG_MAP_SZ)
+ {
+ g_warning("Unrecognized start tag (%s)", name);
+ return;
+ }
+ g_queue_push_head(pd->tag_stack, id.pid);
+ GType gtype = 0;
+ GValue *gval = NULL;
+ GValue *current = g_queue_peek_head(pd->stack);
+ switch (id.id)
+ {
+ case P_PLIST:
+ { // Ignore
+ } break;
+ case P_KEY:
+ {
+ if (pd->key) g_free(pd->key);
+ pd->key = NULL;
+ } break;
+ case P_DICT:
+ {
+ gval = ghb_dict_value_new();
+ g_queue_push_head(pd->stack, gval);
+ } break;
+ case P_ARRAY:
+ {
+ gval = ghb_array_value_new(128);
+ g_queue_push_head(pd->stack, gval);
+ } break;
+ case P_INTEGER:
+ {
+ } break;
+ case P_REAL:
+ {
+ } break;
+ case P_STRING:
+ {
+ } break;
+ case P_DATE:
+ {
+ } break;
+ case P_TRUE:
+ {
+ } break;
+ case P_FALSE:
+ {
+ } break;
+ case P_DATA:
+ {
+ } break;
+ }
+ // Add the element to the current container
+ if (gval)
+ { // There's an element to add
+ if (current == NULL)
+ {
+ pd->plist = gval;
+ return;
+ }
+ gtype = G_VALUE_TYPE(current);
+ if (gtype == ghb_array_get_type())
+ {
+ ghb_array_append(current, gval);
+ }
+ else if (gtype == ghb_dict_get_type())
+ {
+ if (pd->key == NULL)
+ {
+ g_warning("No key for dictionary item");
+ ghb_value_free(gval);
+ }
+ else
+ {
+ ghb_dict_insert(current, g_strdup(pd->key), gval);
+ }
+ }
+ else
+ {
+ g_error("Invalid container type. This shouldn't happen");
+ }
+ }
+}
+
+static void
+end_element(
+ GMarkupParseContext *ctx,
+ const gchar *name,
+ gpointer ud,
+ GError **error)
+{
+ parse_data_t *pd = (parse_data_t*)ud;
+ gint id;
+ union
+ {
+ gint id;
+ gpointer pid;
+ } start_id;
+ gint ii;
+
+ // Check to see if the first element found has been closed
+ // If so, ignore any junk following it.
+ if (pd->closed_top)
+ return;
+
+ for (ii = 0; ii < TAG_MAP_SZ; ii++)
+ {
+ if (strcmp(name, tag_map[ii].tag) == 0)
+ {
+ id = tag_map[ii].id;
+ break;
+ }
+ }
+ if (ii == TAG_MAP_SZ)
+ {
+ g_warning("Unrecognized start tag (%s)", name);
+ return;
+ }
+ start_id.pid = g_queue_pop_head(pd->tag_stack);
+ if (start_id.id != id)
+ g_warning("start tag != end tag: (%s %d) %d", name, id, id);
+
+ GValue *gval = NULL;
+ GValue *current = g_queue_peek_head(pd->stack);
+ GType gtype = 0;
+ switch (id)
+ {
+ case P_PLIST:
+ { // Ignore
+ } break;
+ case P_KEY:
+ {
+ if (pd->key) g_free(pd->key);
+ pd->key = g_strdup(pd->value);
+ return;
+ } break;
+ case P_DICT:
+ {
+ g_queue_pop_head(pd->stack);
+ } break;
+ case P_ARRAY:
+ {
+ g_queue_pop_head(pd->stack);
+ } break;
+ case P_INTEGER:
+ {
+ gint64 val = g_strtod(pd->value, NULL);
+ gval = ghb_int64_value_new(val);
+ } break;
+ case P_REAL:
+ {
+ gdouble val = g_strtod(pd->value, NULL);
+ gval = ghb_double_value_new(val);
+ } break;
+ case P_STRING:
+ {
+ gval = ghb_string_value_new(g_strdup(pd->value));
+ } break;
+ case P_DATE:
+ {
+ GDate date;
+ GTimeVal time;
+ g_time_val_from_iso8601(pd->value, &time);
+ g_date_set_time_val(&date, &time);
+ gval = ghb_date_value_new(&date);
+ } break;
+ case P_TRUE:
+ {
+ gval = ghb_boolean_value_new(TRUE);
+ } break;
+ case P_FALSE:
+ {
+ gval = ghb_boolean_value_new(FALSE);
+ } break;
+ case P_DATA:
+ {
+ ghb_rawdata_t *data;
+ data = g_malloc(sizeof(ghb_rawdata_t));
+ data->data = g_base64_decode(pd->value, &(data->size));
+ gval = ghb_rawdata_value_new(data);
+ } break;
+ }
+ if (gval)
+ {
+ // Get the top of the data structure stack and if it's an array
+ // or dict, add the current element
+ if (current == NULL)
+ {
+ pd->plist = gval;
+ pd->closed_top = TRUE;
+ return;
+ }
+ gtype = G_VALUE_TYPE(current);
+ if (gtype == ghb_array_get_type())
+ {
+ ghb_array_append(current, gval);
+ }
+ else if (gtype == ghb_dict_get_type())
+ {
+ if (pd->key == NULL)
+ {
+ g_warning("No key for dictionary item");
+ ghb_value_free(gval);
+ }
+ else
+ {
+ ghb_dict_insert(current, g_strdup(pd->key), gval);
+ }
+ }
+ else
+ {
+ g_error("Invalid container type. This shouldn't happen");
+ }
+ }
+ if (g_queue_is_empty(pd->stack))
+ pd->closed_top = TRUE;
+}
+
+static void
+text_data(
+ GMarkupParseContext *ctx,
+ const gchar *text,
+ gsize len,
+ gpointer ud,
+ GError **error)
+{
+ parse_data_t *pd = (parse_data_t*)ud;
+ if (pd->value) g_free(pd->value);
+ pd->value = g_strdup(text);
+}
+
+static void
+passthrough(
+ GMarkupParseContext *ctx,
+ const gchar *text,
+ gsize len,
+ gpointer ud,
+ GError **error)
+{
+ //parse_data_t *pd = (parse_data_t*)ud;
+
+ //g_debug("passthrough %s", text);
+}
+
+static void
+parse_error(GMarkupParseContext *ctx, GError *error, gpointer ud)
+{
+ g_warning("Plist parse error: %s", error->message);
+}
+
+// This is required or the parser crashes
+static void
+destroy_notify(gpointer data)
+{ // Do nothing
+ g_debug("destroy parser");
+}
+
+GValue*
+ghb_plist_parse(const gchar *buf, gssize len)
+{
+ GMarkupParseContext *ctx;
+ GMarkupParser parser;
+ parse_data_t pd;
+ GError *err = NULL;
+
+ pd.stack = g_queue_new();
+ pd.tag_stack = g_queue_new();
+ pd.key = NULL;
+ pd.value = NULL;
+ pd.plist = NULL;
+ pd.closed_top = FALSE;
+
+ parser.start_element = start_element;
+ parser.end_element = end_element;
+ parser.text = text_data;
+ parser.passthrough = passthrough;
+ parser.error = parse_error;
+ ctx = g_markup_parse_context_new(&parser, 0, &pd, destroy_notify);
+
+ g_markup_parse_context_parse(ctx, buf, len, &err);
+ g_markup_parse_context_end_parse(ctx, &err);
+ g_markup_parse_context_free(ctx);
+ g_queue_free(pd.stack);
+ g_queue_free(pd.tag_stack);
+ return pd.plist;
+}
+
+GValue*
+ghb_plist_parse_file(const gchar *filename)
+{
+ FILE *fd;
+ gchar *buffer;
+ size_t size;
+ GValue *gval;
+
+ fd = fopen(filename, "r");
+ if (fd == NULL)
+ return NULL;
+ fseek(fd, 0, SEEK_END);
+ size = ftell(fd);
+ fseek(fd, 0, SEEK_SET);
+ buffer = g_malloc(size);
+ size = fread(buffer, 1, size, fd);
+ buffer[size] = 0;
+ gval = ghb_plist_parse(buffer, (gssize)size);
+ g_free(buffer);
+ return gval;
+}
+
+static void
+indent_fprintf(FILE *file, gint indent, const gchar *fmt, ...)
+{
+ va_list ap;
+
+ for (; indent; indent--)
+ putc('\t', file);
+ va_start(ap, fmt);
+ vfprintf(file, fmt, ap);
+ va_end(ap);
+}
+
+// Used for sorting dictionaries.
+static gint
+key_cmp(gconstpointer a, gconstpointer b)
+{
+ gchar *stra = (gchar*)a;
+ gchar *strb = (gchar*)b;
+
+ return strcmp(stra, strb);
+}
+
+static void
+gval_write(FILE *file, GValue *gval)
+{
+ static gint indent = 0;
+ gint ii;
+ GType gtype;
+
+ if (gval == NULL) return;
+ gtype = G_VALUE_TYPE(gval);
+ if (gtype == ghb_array_get_type())
+ {
+ GValue *val;
+ gint count;
+
+ indent_fprintf(file, indent, "<array>\n");
+ indent++;
+ count = ghb_array_len(gval);
+ for (ii = 0; ii < count; ii++)
+ {
+ val = ghb_array_get_nth(gval, ii);
+ gval_write(file, val);
+ }
+ indent--;
+ indent_fprintf(file, indent, "</array>\n");
+ }
+ else if (gtype == ghb_dict_get_type())
+ {
+ GValue *val;
+ GHashTable *dict = g_value_get_boxed(gval);
+ GList *link, *keys;
+ keys = g_hash_table_get_keys(dict);
+ // Sort the dictionary. Not really necessray, but it makes
+ // finding things easier
+ keys = g_list_sort(keys, key_cmp);
+ link = keys;
+ indent_fprintf(file, indent, "<dict>\n");
+ indent++;
+ while (link)
+ {
+ gchar *key = (gchar*)link->data;
+ val = g_hash_table_lookup(dict, key);
+ indent_fprintf(file, indent, "<key>%s</key>\n", key);
+ gval_write(file, val);
+ link = link->next;
+ }
+ indent--;
+ indent_fprintf(file, indent, "</dict>\n");
+ g_list_free(keys);
+ }
+ else if (gtype == G_TYPE_BOOLEAN)
+ {
+ gchar *tag;
+ if (g_value_get_boolean(gval))
+ {
+ tag = "true";
+ }
+ else
+ {
+ tag = "false";
+ }
+ indent_fprintf(file, indent, "<%s />\n", tag);
+ }
+ else if (gtype == g_date_get_type())
+ {
+ GDate *date;
+ date = g_value_get_boxed(gval);
+ indent_fprintf(file, indent, "<date>%d-%d-%d</date>\n",
+ g_date_get_year(date),
+ g_date_get_month(date),
+ g_date_get_day(date)
+ );
+ }
+ else if (gtype == ghb_rawdata_get_type())
+ {
+ ghb_rawdata_t *data;
+ gchar *base64;
+ data = g_value_get_boxed(gval);
+ base64 = g_base64_encode(data->data, data->size);
+ indent_fprintf(file, indent, "<data>\n");
+ indent_fprintf(file, 0, "%s\n", base64);
+ indent_fprintf(file, indent, "</data>\n");
+ g_free(base64);
+ }
+ else if (gtype == G_TYPE_DOUBLE)
+ {
+ gdouble val = g_value_get_double(gval);
+ indent_fprintf(file, indent, "<real>%.17g</real>\n", val);
+ }
+ else if (gtype == G_TYPE_INT64)
+ {
+ gint val = g_value_get_int64(gval);
+ indent_fprintf(file, indent, "<integer>%d</integer>\n", val);
+ }
+ else if (gtype == G_TYPE_STRING)
+ {
+ const gchar *str = g_value_get_string(gval);
+ gchar *esc = g_markup_escape_text(str, -1);
+ indent_fprintf(file, indent, "<string>%s</string>\n", esc);
+ g_free(esc);
+ }
+ else
+ {
+ // Try to make anything thats unrecognized into a string
+ const gchar *str;
+ GValue val = {0,};
+ g_value_init(&val, G_TYPE_STRING);
+ if (g_value_transform(gval, &val))
+ {
+ str = g_value_get_string(&val);
+ gchar *esc = g_markup_escape_text(str, -1);
+ indent_fprintf(file, indent, "<string>%s</string>\n", esc);
+ g_free(esc);
+ }
+ else
+ {
+ g_message("failed to transform");
+ }
+ g_value_unset(&val);
+ }
+}
+
+void
+ghb_plist_write(FILE *file, GValue *gval)
+{
+ fprintf(file, "%s", preamble);
+ gval_write(file, gval);
+ fprintf(file, "%s", postfix);
+}
+
+void
+ghb_plist_write_file(const gchar *filename, GValue *gval)
+{
+ FILE *file;
+
+ file = fopen(filename, "w");
+ if (file == NULL)
+ return;
+
+ fprintf(file, "%s", preamble);
+ gval_write(file, gval);
+ fprintf(file, "%s", postfix);
+}
+
+
+#if defined(PL_TEST)
+gint
+main(gint argc, gchar *argv[])
+{
+ GValue *gval;
+
+ g_type_init();
+
+ gval = ghb_plist_parse_file(argv[1]);
+ if (argc > 2)
+ ghb_plist_write_file(argv[2], gval);
+ else
+ ghb_plist_write(stdout, gval);
+ return 0;
+}
+#endif
diff --git a/gtk/src/plist.h b/gtk/src/plist.h
new file mode 100644
index 000000000..8b2498826
--- /dev/null
+++ b/gtk/src/plist.h
@@ -0,0 +1,14 @@
+#if !defined(_PLIST_H_)
+#define _PLIST_H_
+
+#include <stdio.h>
+#include <glib.h>
+#include <glib-object.h>
+
+GValue* ghb_plist_parse(const gchar *buf, gssize len);
+GValue* ghb_plist_parse_file(const gchar *filename);
+void ghb_plist_write(FILE *file, GValue *gval);
+void ghb_plist_write_file(const gchar *filename, GValue *gval);
+
+#endif // _PLIST_H_
+
diff --git a/gtk/src/preset_to_string.c b/gtk/src/preset_to_string.c
index e678e994b..e1816637b 100644
--- a/gtk/src/preset_to_string.c
+++ b/gtk/src/preset_to_string.c
@@ -16,7 +16,8 @@ int
main(int argc, char *argv[])
{
FILE *infile, *outfile;
- char buffer[BUF_SIZE];
+ char in_buffer[BUF_SIZE];
+ char out_buffer[2*BUF_SIZE];
if (argc < 2 || argc > 3)
{
@@ -32,17 +33,31 @@ main(int argc, char *argv[])
{
outfile = fopen(argv[2], "w");
}
- while (fgets(buffer, BUF_SIZE, infile) != NULL)
+ while (fgets(in_buffer, BUF_SIZE, infile) != NULL)
{
+ int ii, jj;
int len;
// Step on any CR LF at end of line
- len = strlen(buffer);
- if (buffer[len-1] == '\n' || buffer[len-1] == '\r')
- buffer[len-1] = 0;
- if (buffer[len-2] == '\n' || buffer[len-2] == '\r')
- buffer[len-2] = 0;
- fprintf(outfile, "\"%s\\n\"\n", buffer);
+ len = strlen(in_buffer);
+ for (jj = 0, ii = 0; ii < len; ii++)
+ {
+ if (in_buffer[ii] == '"')
+ {
+ out_buffer[jj++] = '\\';
+ out_buffer[jj++] = in_buffer[ii];
+ }
+ else if (in_buffer[ii] == '\n' || in_buffer[ii] == '\r')
+ { // Skip it
+ }
+ else
+ {
+ out_buffer[jj++] = in_buffer[ii];
+ }
+ }
+ out_buffer[jj] = 0;
+ fprintf(outfile, "\"%s\\n\"\n", out_buffer);
}
- close(infile);
- close(outfile);
+ fclose(infile);
+ fclose(outfile);
+ return 0;
}
diff --git a/gtk/src/presets.c b/gtk/src/presets.c
new file mode 100644
index 000000000..75ef74538
--- /dev/null
+++ b/gtk/src/presets.c
@@ -0,0 +1,722 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * presets.c
+ * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
+ *
+ * presets.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 <glib.h>
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include "settings.h"
+#include "plist.h"
+#include "presets.h"
+#include "values.h"
+
+//
+// Internal defaults stored in character arrays and parsed
+// the same as external settings files.
+const gchar defaultSettings[] =
+#include "internal_defaults.h"
+;
+const gchar standardPresets[] =
+#include "standard_presets.h"
+;
+
+static GValue *presetsPlist = NULL;
+static GValue *internalPlist = NULL;
+static GValue *prefsPlist = NULL;
+
+static GValue*
+plist_get_dict(GValue *presets, const gchar *name)
+{
+ if (presets == NULL || name == NULL) return NULL;
+ return ghb_dict_lookup(presets, name);
+}
+
+void
+ghb_set_preset_default(GValue *settings)
+{
+ gchar *preset;
+
+ preset = ghb_settings_get_string (settings, "preset");
+ ghb_settings_set_string(settings, "default_preset", preset);
+ ghb_prefs_save(settings);
+ g_free(preset);
+}
+
+// Used for sorting dictionaries.
+gint
+key_cmp(gconstpointer a, gconstpointer b)
+{
+ gchar *stra = (gchar*)a;
+ gchar *strb = (gchar*)b;
+
+ return strcmp(stra, strb);
+}
+
+gchar*
+ghb_presets_get_description(const gchar *name)
+{
+ GValue *pdict;
+ pdict = plist_get_dict(presetsPlist, name);
+ if (pdict == NULL) return g_strdup("");
+ return ghb_value_string(ghb_dict_lookup(pdict, "preset_description"));
+}
+
+static const GValue*
+preset_dict_get_value(
+ GValue *dict,
+ const gchar *key)
+{
+ const GValue *gval = NULL;
+
+ if (dict)
+ {
+ gval = ghb_dict_lookup(dict, key);
+ }
+ if (internalPlist == NULL) return NULL;
+ if (gval == NULL)
+ {
+ dict = plist_get_dict(internalPlist, "Presets");
+ if (dict == NULL) return NULL;
+ gval = ghb_dict_lookup(dict, key);
+ }
+ return gval;
+}
+
+static const GValue*
+preset_get_value(
+ const gchar *name,
+ const gchar *key)
+{
+ GValue *dict;
+
+ dict = plist_get_dict(presetsPlist, name);
+ return preset_dict_get_value(dict, key);
+}
+
+GList*
+ghb_presets_get_names()
+{
+ GHashTable *dict;
+ GList *names, *link;
+ GList *standard = NULL;
+ GList *custom = NULL;
+
+ if (presetsPlist == NULL) return NULL;
+ dict = g_value_get_boxed(presetsPlist);
+ link = names = g_hash_table_get_keys(dict);
+ while (link)
+ {
+ gchar *name;
+ gint ptype;
+
+ name = (gchar*)link->data;
+ ptype = ghb_value_int(preset_get_value(name, "preset_type"));
+ if (ptype)
+ custom = g_list_append(custom, name);
+ else
+ standard = g_list_append(standard, name);
+ link = link->next;
+ }
+ custom = g_list_sort(custom, key_cmp);
+ standard = g_list_sort(standard, key_cmp);
+ g_list_free(names);
+ names = g_list_concat(standard, custom);
+ return names;
+}
+
+gint
+ghb_preset_flags(const gchar *name)
+{
+ GValue *dict;
+ const GValue *gval;
+ gint ptype;
+ gint ret = 0;
+
+ dict = plist_get_dict(presetsPlist, name);
+ gval = preset_dict_get_value(dict, "preset_type");
+ if (gval)
+ {
+ ptype = ghb_value_int(gval);
+ ret = (ptype != 0 ? PRESET_CUSTOM : 0);
+ }
+ return ret;
+}
+
+static void init_settings_from_dict(
+ GValue *dest, GValue *internal, GValue *dict);
+
+static void
+init_settings_from_array(
+ GValue *dest,
+ GValue *internal,
+ GValue *array)
+{
+ GValue *gval, *val;
+ gint count, ii;
+
+ count = ghb_array_len(array);
+ // The first element of the internal version is always the
+ // template for the allowed values
+ gval = ghb_array_get_nth(internal, 0);
+ for (ii = 0; ii < count; ii++)
+ {
+ val = NULL;
+ val = ghb_array_get_nth(array, ii);
+ if (val == NULL)
+ val = gval;
+ if (G_VALUE_TYPE(gval) == ghb_dict_get_type())
+ {
+ GValue *new_dict;
+ new_dict = ghb_dict_value_new();
+ ghb_array_append(dest, new_dict);
+ if (G_VALUE_TYPE(val) == ghb_dict_get_type())
+ init_settings_from_dict(new_dict, gval, val);
+ else
+ init_settings_from_dict(new_dict, gval, gval);
+ }
+ else if (G_VALUE_TYPE(gval) == ghb_array_get_type())
+ {
+ GValue *new_array;
+ new_array = ghb_array_value_new(8);
+ ghb_array_append(dest, new_array);
+ if (G_VALUE_TYPE(val) == ghb_array_get_type())
+ init_settings_from_array(new_array, gval, val);
+ else
+ init_settings_from_array(new_array, gval, gval);
+ }
+ else
+ {
+ ghb_array_append(dest, val);
+ }
+ }
+}
+
+static void
+init_settings_from_dict(
+ GValue *dest,
+ GValue *internal,
+ GValue *dict)
+{
+ GHashTableIter iter;
+ gchar *key;
+ GValue *gval, *val;
+
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ val = NULL;
+ if (dict)
+ val = ghb_dict_lookup(dict, key);
+ if (val == NULL)
+ val = gval;
+ if (G_VALUE_TYPE(gval) == ghb_dict_get_type())
+ {
+ GValue *new_dict;
+ new_dict = ghb_dict_value_new();
+ ghb_settings_take_value(dest, key, new_dict);
+ if (G_VALUE_TYPE(val) == ghb_dict_get_type())
+ init_settings_from_dict(new_dict, gval, val);
+ else
+ init_settings_from_dict(new_dict, gval, gval);
+ }
+ else if (G_VALUE_TYPE(gval) == ghb_array_get_type())
+ {
+ GValue *new_array;
+ new_array = ghb_array_value_new(8);
+ ghb_settings_take_value(dest, key, new_array);
+ if (G_VALUE_TYPE(val) == ghb_array_get_type())
+ init_settings_from_array(new_array, gval, val);
+ else
+ init_settings_from_array(new_array, gval, gval);
+
+ }
+ else
+ {
+ ghb_settings_set_value(dest, key, val);
+ }
+ }
+}
+
+void
+init_ui_from_dict(
+ signal_user_data_t *ud,
+ GValue *internal,
+ GValue *dict)
+{
+ GHashTableIter iter;
+ gchar *key;
+ GValue *gval, *val;
+
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ val = NULL;
+ if (dict)
+ val = ghb_dict_lookup(dict, key);
+ if (val == NULL)
+ val = gval;
+ ghb_ui_update(ud, key, val);
+ }
+}
+
+static void
+preset_to_ui(signal_user_data_t *ud, GValue *dict)
+{
+ g_debug("preset_to_ui()\n");
+ // Initialize the ui from presets file.
+ GValue *internal;
+
+ // Get key list from internal default presets. This way we do not
+ // load any unknown keys.
+ if (internalPlist == NULL) return;
+ internal = plist_get_dict(internalPlist, "Presets");
+ // Setting a ui widget will cause the corresponding setting
+ // to be set, but it also triggers a callback that can
+ // have the side effect of using other settings values
+ // that have not yet been set. So set *all* settings first
+ // then update the ui.
+ init_settings_from_dict(ud->settings, internal, dict);
+ init_ui_from_dict(ud, internal, dict);
+
+ if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
+ {
+ const GValue *gval;
+ gval = preset_dict_get_value(dict, "deinterlace");
+ if (gval)
+ {
+ ghb_ui_update(ud, "tweak_deinterlace", gval);
+ }
+ gval = preset_dict_get_value(dict, "denoise");
+ if (gval)
+ {
+ ghb_ui_update(ud, "tweak_denoise", gval);
+ }
+ }
+}
+
+void
+ghb_set_preset(signal_user_data_t *ud, const gchar *name)
+{
+ GValue *dict;
+
+ g_debug("ghb_set_preset() %s\n", name);
+ if (name == NULL)
+ {
+ GList *presets;
+ // Try to get the first preset
+ presets = ghb_presets_get_names();
+ if (presets)
+ {
+ name = (const gchar*)presets->data;
+ g_list_free(presets);
+ }
+ }
+ dict = plist_get_dict(presetsPlist, name);
+ if (dict == NULL || name == NULL)
+ {
+ preset_to_ui(ud, NULL);
+ }
+ else
+ {
+ preset_to_ui(ud, dict);
+ ghb_settings_set_string(ud->settings, "preset", name);
+ }
+}
+
+void
+ghb_update_from_preset(
+ signal_user_data_t *ud,
+ const gchar *name,
+ const gchar *key)
+{
+ const GValue *gval;
+
+ g_debug("ghb_update_from_preset() %s %s", name, key);
+ if (name == NULL) return;
+ gval = preset_get_value(name, key);
+ if (gval != NULL)
+ {
+ ghb_ui_update(ud, key, gval);
+ }
+}
+
+static void
+store_plist(GValue *plist, const gchar *name)
+{
+ const gchar *dir;
+ gchar *config;
+ FILE *file;
+
+ dir = g_get_user_config_dir();
+ config = g_strdup_printf ("%s/ghb", dir);
+ if (!g_file_test(config, G_FILE_TEST_IS_DIR))
+ {
+ g_mkdir (config, 0755);
+ }
+ g_free(config);
+ config = g_strdup_printf ("%s/ghb/%s", dir, name);
+ file = g_fopen(config, "w");
+ g_free(config);
+ ghb_plist_write(file, plist);
+ fclose(file);
+}
+
+static gboolean prefs_initializing = FALSE;
+
+void
+ghb_prefs_to_ui(signal_user_data_t *ud)
+{
+ const GValue *gval;
+ gchar *key;
+ gchar *str;
+ GValue *internal, *dict;
+ GHashTableIter iter;
+
+
+ prefs_initializing = TRUE;
+
+ // Setting a ui widget will cause the corresponding setting
+ // to be set, but it also triggers a callback that can
+ // have the side effect of using other settings values
+ // that have not yet been set. So set *all* settings first
+ // then update the ui.
+ internal = plist_get_dict(internalPlist, "Initialization");
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ ghb_ui_update(ud, key, gval);
+ }
+
+ dict = plist_get_dict(prefsPlist, "Preferences");
+ internal = plist_get_dict(internalPlist, "Preferences");
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ const GValue *value = NULL;
+ if (dict)
+ value = ghb_dict_lookup(dict, key);
+ if (value == NULL)
+ value = gval;
+ ghb_settings_set_value(ud->settings, key, value);
+ }
+ internal = plist_get_dict(internalPlist, "Preferences");
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ const GValue *value = NULL;
+ if (dict)
+ value = ghb_dict_lookup(dict, key);
+ if (value == NULL)
+ value = gval;
+ ghb_ui_update(ud, key, value);
+ }
+ const GValue *val;
+ val = ghb_settings_get_value(ud->settings, "show_presets");
+ ghb_ui_update(ud, "show_presets", val);
+ if (ghb_settings_get_boolean(ud->settings, "hbfd_feature"))
+ {
+ GtkAction *action;
+ val = ghb_settings_get_value(ud->settings, "hbfd");
+ ghb_ui_update(ud, "hbfd", val);
+ action = GHB_ACTION (ud->builder, "hbfd");
+ gtk_action_set_visible(action, TRUE);
+ }
+ else
+ {
+ ghb_ui_update(ud, "hbfd", ghb_int64_value(0));
+ }
+ gval = ghb_settings_get_value(ud->settings, "default_source");
+ ghb_settings_set_value (ud->settings, "source", gval);
+ str = ghb_settings_get_string(ud->settings, "destination_dir");
+
+ gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
+ ghb_ui_update(ud, "destination", ghb_string_value(path));
+ g_free(str);
+ g_free(path);
+
+ prefs_initializing = FALSE;
+}
+
+void
+ghb_prefs_save(GValue *settings)
+{
+ GValue *dict;
+ GValue *pref_dict;
+ GHashTableIter iter;
+ gchar *key;
+ const GValue *value;
+
+ if (prefs_initializing) return;
+ dict = plist_get_dict(internalPlist, "Preferences");
+ if (dict == NULL) return;
+ pref_dict = plist_get_dict(prefsPlist, "Preferences");
+ if (pref_dict == NULL) return;
+ ghb_dict_iter_init(&iter, dict);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&value))
+ {
+ value = ghb_settings_get_value(settings, key);
+ if (value != NULL)
+ {
+ ghb_dict_insert(pref_dict, g_strdup(key), ghb_value_dup(value));
+ }
+ }
+ store_plist(prefsPlist, "preferences");
+}
+
+void
+ghb_pref_save(GValue *settings, const gchar *key)
+{
+ const GValue *value;
+
+ if (prefs_initializing) return;
+ value = ghb_settings_get_value(settings, key);
+ if (value != NULL)
+ {
+ GValue *dict;
+ dict = plist_get_dict(prefsPlist, "Preferences");
+ if (dict == NULL) return;
+ ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
+ store_plist(prefsPlist, "preferences");
+ }
+}
+
+void
+ghb_settings_init(signal_user_data_t *ud)
+{
+ GValue *internal;
+ GHashTableIter iter;
+ gchar *key;
+ GValue *gval;
+
+
+ g_debug("ghb_settings_init");
+ prefs_initializing = TRUE;
+
+ internalPlist = ghb_plist_parse(defaultSettings, sizeof(defaultSettings)-1);
+ // Setting a ui widget will cause the corresponding setting
+ // to be set, but it also triggers a callback that can
+ // have the side effect of using other settings values
+ // that have not yet been set. So set *all* settings first
+ // then update the ui.
+ internal = plist_get_dict(internalPlist, "Initialization");
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ ghb_settings_set_value(ud->settings, key, gval);
+ }
+
+ internal = plist_get_dict(internalPlist, "Presets");
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ ghb_settings_set_value(ud->settings, key, gval);
+ }
+
+ internal = plist_get_dict(internalPlist, "Preferences");
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ ghb_settings_set_value(ud->settings, key, gval);
+ }
+ prefs_initializing = FALSE;
+}
+
+void
+ghb_prefs_load(signal_user_data_t *ud)
+{
+ const gchar *dir;
+ gchar *config;
+ GValue *dict, *internal;
+ GHashTableIter iter;
+ gchar *key;
+ GValue *gval;
+
+ g_debug("ghb_prefs_load");
+ dir = g_get_user_config_dir();
+ config = g_strdup_printf ("%s/ghb/preferences", dir);
+ if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
+ {
+ prefsPlist = ghb_plist_parse_file(config);
+ if (prefsPlist == NULL)
+ prefsPlist = ghb_dict_value_new();
+ }
+ else
+ {
+ // Make an empty plist
+ prefsPlist = ghb_dict_value_new();
+ }
+ g_free(config);
+ dict = plist_get_dict(prefsPlist, "Preferences");
+ internal = plist_get_dict(internalPlist, "Preferences");
+ if (dict == NULL && internal)
+ {
+ dict = ghb_dict_value_new();
+ ghb_dict_insert(prefsPlist, g_strdup("Preferences"), dict);
+
+ // Get defaults from internal defaults
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
+ }
+ const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
+ ghb_dict_insert(dict,
+ g_strdup("destination_dir"), ghb_value_dup(ghb_string_value(dir)));
+ store_plist(prefsPlist, "preferences");
+ }
+
+}
+
+void
+ghb_presets_reload(signal_user_data_t *ud)
+{
+ GValue *std_dict, *dict;
+ GHashTableIter std_iter;
+
+ g_debug("ghb_presets_reload()\n");
+ std_dict = ghb_plist_parse(standardPresets, sizeof(standardPresets)-1);
+ if (std_dict == NULL) return;
+
+ // Merge the keyfile contents into our presets
+ gchar *name;
+ GValue *orig_dict;
+
+ ghb_dict_iter_init(&std_iter, std_dict);
+ while (g_hash_table_iter_next(&std_iter, (gpointer*)&name, (gpointer*)&orig_dict))
+ {
+ GHashTableIter iter;
+ gchar *key;
+ GValue *value;
+
+ dict = ghb_dict_value_new();
+ ghb_dict_insert(presetsPlist, g_strdup(name), dict);
+ ghb_dict_iter_init(&iter, orig_dict);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&value))
+ {
+ ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
+ }
+ }
+ ghb_value_free(std_dict);
+ store_plist(presetsPlist, "presets");
+}
+
+static void
+presets_store()
+{
+ g_debug("presets_store ()\n");
+ store_plist(presetsPlist, "presets");
+}
+
+void
+ghb_presets_load()
+{
+ const gchar *dir;
+ gchar *config;
+
+ dir = g_get_user_config_dir();
+ config = g_strdup_printf ("%s/ghb/presets", dir);
+ if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
+ {
+ presetsPlist = ghb_plist_parse_file(config);
+ if (presetsPlist == NULL)
+ {
+ presetsPlist = ghb_plist_parse(
+ standardPresets, sizeof(standardPresets)-1);
+ presets_store();
+ }
+ }
+ else
+ {
+ presetsPlist = ghb_plist_parse(
+ standardPresets, sizeof(standardPresets)-1);
+ }
+ g_free(config);
+}
+
+void
+ghb_settings_save(signal_user_data_t *ud, const gchar *name)
+{
+ GValue *dict, *internal;
+ GHashTableIter iter;
+ gchar *key;
+ GValue *value;
+ gboolean autoscale;
+
+ if (internalPlist == NULL) return;
+ if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
+ {
+ gchar *str;
+ str = ghb_settings_get_string(ud->settings, "tweak_deinterlace");
+ if (str)
+ {
+ ghb_settings_set_string(ud->settings, "deinterlace", str);
+ g_free(str);
+ }
+ str = ghb_settings_get_string(ud->settings, "tweak_denoise");
+ if (str)
+ {
+ ghb_settings_set_string(ud->settings, "denoise", str);
+ g_free(str);
+ }
+ }
+ autoscale = ghb_settings_get_boolean(ud->settings, "autoscale");
+ ghb_settings_set_int64(ud->settings, "preset_type", 1);
+
+ dict = ghb_dict_value_new();
+ ghb_dict_insert(presetsPlist, g_strdup(name), dict);
+ internal = plist_get_dict(internalPlist, "Presets");
+
+ ghb_dict_iter_init(&iter, internal);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&value))
+ {
+ if (!autoscale)
+ {
+ if (strcmp(key, "scale_width"))
+ {
+ key = "max_width";
+ }
+ if (strcmp(key, "scale_height"))
+ {
+ key = "max_height";
+ }
+ }
+ const GValue *gval;
+ gval = ghb_settings_get_value(ud->settings, key);
+ if (gval == NULL)
+ {
+ g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
+ continue;
+ }
+ if (ghb_value_cmp(gval, value) != 0)
+ {
+ // Differs from default value. Store it.
+ ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
+ }
+ }
+ presets_store();
+ ud->dont_clear_presets = TRUE;
+ ghb_set_preset (ud, name);
+ ud->dont_clear_presets = FALSE;
+}
+
+void
+ghb_presets_remove(const gchar *name)
+{
+ if (ghb_dict_lookup(presetsPlist, name))
+ {
+ ghb_dict_remove(presetsPlist, name);
+ presets_store();
+ }
+}
+
diff --git a/gtk/src/presets.h b/gtk/src/presets.h
new file mode 100644
index 000000000..44f9cdd9b
--- /dev/null
+++ b/gtk/src/presets.h
@@ -0,0 +1,37 @@
+/*
+ * This program is free software; you can 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.
+ *
+ * This program 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
+ */
+#if !defined(_GHB_PRESETS_H_)
+#define _GHB_PRESETS_H_
+
+gint ghb_preset_flags(const gchar *name);
+GList* ghb_presets_get_names(void);
+gchar* ghb_presets_get_description(const gchar *name);
+
+void ghb_settings_save(signal_user_data_t *ud, const gchar *name);
+void ghb_presets_load(void);
+void ghb_presets_reload(signal_user_data_t *ud);
+void ghb_set_preset(signal_user_data_t *ud, const gchar *name);
+void ghb_update_from_preset(
+ signal_user_data_t *ud, const gchar *name, const gchar *key);
+void ghb_presets_remove(const gchar *name);
+void ghb_prefs_load(signal_user_data_t *ud);
+void ghb_settings_init(signal_user_data_t *ud);
+void ghb_prefs_to_ui(signal_user_data_t *ud);
+void ghb_prefs_save(GValue *settings);
+void ghb_pref_save(GValue *settings, const gchar *key);
+void ghb_set_preset_default(GValue *settings);
+
+#endif // _GHB_PRESETS_H_
diff --git a/gtk/src/settings.c b/gtk/src/settings.c
index 362dfff2f..4f2cacbb8 100644
--- a/gtk/src/settings.c
+++ b/gtk/src/settings.c
@@ -19,8 +19,9 @@
#include <gtk/gtk.h>
#include "settings.h"
#include "hb-backend.h"
+#include "values.h"
-void dump_settings(GHashTable *settings);
+void dump_settings(GValue *settings);
void ghb_pref_audio_init(signal_user_data_t *ud);
GObject*
@@ -30,251 +31,179 @@ debug_get_object(GtkBuilder* b, const gchar *n)
return gtk_builder_get_object(b, n);
}
-static gchar *true_strings[] =
-{
- "enable",
- "yes",
- "true",
- "1"
-};
-
-static gboolean
-string_is_true(const gchar *str)
-{
- gint count = sizeof(true_strings) / sizeof(gchar*);
- gint ii;
-
- for (ii = 0; ii < count; ii++)
- {
- if (strcmp(str, true_strings[ii]) == 0)
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static void
-delete_key(gpointer str)
-{
- g_debug("delete_key (%s)\n", (gchar*)str);
- g_free(str);
-}
-
-static void
-delete_value(gpointer val)
+GValue*
+ghb_settings_new()
{
- g_debug("delete_value (%s)\n", ((setting_value_t*)val)->svalue);
- g_free(((setting_value_t*)val)->svalue);
- g_free(((setting_value_t*)val)->option);
- g_free(((setting_value_t*)val)->shortOpt);
- g_free(val);
+ return ghb_dict_value_new();
}
void
-ghb_free_setting_value(setting_value_t *val)
+ghb_settings_set_value(
+ GValue *settings,
+ const gchar *key,
+ const GValue *value)
{
- delete_value((gpointer)val);
-}
-
-GHashTable*
-ghb_settings_new()
-{
- GHashTable* settings;
-
- g_debug("ghb_settings_new ()\n");
- settings = g_hash_table_new_full(g_str_hash, g_str_equal,
- delete_key, delete_value);
- return settings;
+ if (key == NULL || value == NULL)
+ return;
+ ghb_dict_insert(settings, g_strdup(key), ghb_value_dup(value));
}
-static void
-settings_set(GHashTable *settings, const gchar *key,
- const gchar *str, gint val, gdouble dbl)
+void
+ghb_settings_take_value(GValue *settings, const gchar *key, GValue *value)
{
- g_debug("setting_set () key (%s), svalue (%s), ivalue %d, dvalue %.2g\n", key, str, val, dbl);
- setting_value_t *value = g_malloc(sizeof(setting_value_t));
- if (str != NULL)
- value->svalue = g_strdup(str);
- else
- value->svalue = g_strdup("");
- value->option = g_strdup(value->svalue);
- value->shortOpt = g_strdup(value->svalue);
- value->index = val;
- value->ivalue = val;
- value->dvalue = dbl;
- g_hash_table_insert(settings, g_strdup(key), value);
+ ghb_dict_insert(settings, g_strdup(key), value);
}
-static setting_value_t*
-copy_settings_value(const setting_value_t *value)
+void
+ghb_settings_set_string(
+ GValue *settings,
+ const gchar *key,
+ const gchar *sval)
{
- setting_value_t *copy = g_malloc(sizeof(setting_value_t));
- copy->index = value->index;
- copy->ivalue = value->ivalue;
- copy->dvalue = value->dvalue;
- copy->svalue = g_strdup(value->svalue);
- copy->option = g_strdup(value->option);
- copy->shortOpt = g_strdup(value->shortOpt);
- return copy;
+ GValue *value;
+ value = ghb_string_value_new(sval);
+ ghb_dict_insert(settings, g_strdup(key), value);
}
void
-ghb_settings_set(GHashTable *settings, const gchar *key, setting_value_t *value)
+ghb_settings_set_double(GValue *settings, const gchar *key, gdouble dval)
{
- g_debug("ghb_settings_set () key (%s)\n", key);
- if ((key == NULL) || (value == NULL))
- {
- g_debug("Bad key or value\n");
- return;
- }
- g_debug("ghb_settings_set key (%s) -- value (%d,%d,%s,%s,%s)\n", key,
- value->index, value->ivalue, value->option, value->shortOpt,
- value->svalue);
- g_hash_table_insert(settings, g_strdup(key), value);
+ GValue *value;
+ value = ghb_double_value_new(dval);
+ ghb_dict_insert(settings, g_strdup(key), value);
}
void
-ghb_settings_set_string(GHashTable *settings, const gchar *key, const gchar *str)
+ghb_settings_set_int64(GValue *settings, const gchar *key, gint64 ival)
{
- gdouble dvalue = 0;
- gchar *end;
-
- if (str == NULL) str = "";
- dvalue = g_strtod (str, &end);
- if ((end == str) && string_is_true (str))
- {
- dvalue = 1;
- }
- settings_set(settings, key, str, dvalue, dvalue);
+ GValue *value;
+ value = ghb_int64_value_new(ival);
+ ghb_dict_insert(settings, g_strdup(key), value);
}
void
-ghb_settings_set_dbl(GHashTable *settings, const gchar *key, gdouble dvalue)
+ghb_settings_set_int(GValue *settings, const gchar *key, gint ival)
{
- setting_value_t *value;
-
- value = g_malloc(sizeof(setting_value_t));
- value->index = 0;
- value->dvalue = dvalue;
- value->option = g_strdup_printf("%.8g", dvalue);
- value->shortOpt = g_strdup(value->option);
- value->svalue = g_strdup(value->option);
- value->ivalue = dvalue;
- ghb_settings_set( settings, key, value);
+ GValue *value;
+ value = ghb_int64_value_new((gint64)ival);
+ ghb_dict_insert(settings, g_strdup(key), value);
}
void
-ghb_settings_copy(GHashTable *settings, const gchar *key, const setting_value_t *value)
+ghb_settings_set_boolean(GValue *settings, const gchar *key, gboolean bval)
{
- setting_value_t *copy = copy_settings_value(value);
- g_hash_table_insert(settings, g_strdup(key), copy);
+ GValue *value;
+ value = ghb_boolean_value_new(bval);
+ ghb_dict_insert(settings, g_strdup(key), value);
}
-const setting_value_t*
-ghb_settings_get(GHashTable *settings, const gchar *key)
-{
- const setting_value_t* value;
- g_debug("ghb_settings_get () key (%s)\n", key);
- value = g_hash_table_lookup(settings, key);
+void
+ghb_settings_set_combo(
+ GValue *settings,
+ const gchar *key,
+ gint index,
+ const gchar *option,
+ const gchar *shortOpt,
+ const gchar *svalue,
+ gint ivalue)
+{
+ GValue *value;
+ value = ghb_combo_value_new(index, option, shortOpt, svalue, ivalue);
+ ghb_dict_insert(settings, g_strdup(key), value);
+}
+
+GValue*
+ghb_settings_get_value(GValue *settings, const gchar *key)
+{
+ GValue *value;
+ value = ghb_dict_lookup(settings, key);
+ if (value == NULL)
+ g_warning("returning null (%s)", key);
return value;
}
gboolean
-ghb_settings_get_bool(GHashTable *settings, const gchar *key)
+ghb_settings_get_boolean(GValue *settings, const gchar *key)
{
- const setting_value_t* value;
- g_debug("ghb_settings_get_bool () key (%s)\n", key);
- value = ghb_settings_get(settings, key);
- if (value == NULL)
- {
- g_debug("\tNo value found\n");
- return FALSE;
- }
- g_debug("\tvalue is %d\n", value->ivalue);
- return value->ivalue;
+ const GValue* value;
+ value = ghb_settings_get_value(settings, key);
+ if (value == NULL) return FALSE;
+ return ghb_value_boolean(value);
}
-gint
-ghb_settings_get_int(GHashTable *settings, const gchar *key)
+gint64
+ghb_settings_get_int64(GValue *settings, const gchar *key)
{
- const setting_value_t* value;
- g_debug("ghb_settings_get_int () key (%s)\n", key);
- value = ghb_settings_get(settings, key);
+ const GValue* value;
+ value = ghb_settings_get_value(settings, key);
if (value == NULL) return 0;
- return value->ivalue;
+ return ghb_value_int64(value);
}
gint
-ghb_settings_get_index(GHashTable *settings, const gchar *key)
+ghb_settings_get_int(GValue *settings, const gchar *key)
{
- const setting_value_t* value;
- g_debug("ghb_settings_get_index () key (%s)\n", key);
- value = ghb_settings_get(settings, key);
+ const GValue* value;
+ value = ghb_settings_get_value(settings, key);
if (value == NULL) return 0;
- return value->index;
+ return ghb_value_int(value);
}
gdouble
-ghb_settings_get_dbl(GHashTable *settings, const gchar *key)
-{
- const setting_value_t* value;
- g_debug("ghb_settings_get_dbl () key (%s)\n", key);
- value = ghb_settings_get(settings, key);
- if (value == NULL) return 0.0;
- return value->dvalue;
-}
-
-const gchar*
-ghb_settings_get_string(GHashTable *settings, const gchar *key)
+ghb_settings_get_double(GValue *settings, const gchar *key)
{
- const setting_value_t* value;
- g_debug("ghb_settings_get_string () key (%s)\n", key);
- value = ghb_settings_get(settings, key);
- if (value == NULL) return "";
- return value->svalue;
-
+ const GValue* value;
+ value = ghb_settings_get_value(settings, key);
+ if (value == NULL) return 0;
+ return ghb_value_double(value);
}
-const gchar*
-ghb_settings_get_option(GHashTable *settings, const gchar *key)
+gchar*
+ghb_settings_get_string(GValue *settings, const gchar *key)
{
- const setting_value_t* value;
- g_debug("ghb_settings_get_option () key (%s)\n", key);
- value = ghb_settings_get(settings, key);
- if (value == NULL) return "";
- g_debug("option: (%s)\n", value->option);
- return value->option;
+ const GValue* value;
+ value = ghb_settings_get_value(settings, key);
+ if (value == NULL) return g_strdup("");
+ return ghb_value_string(value);
}
-const gchar*
-ghb_settings_get_short_opt(GHashTable *settings, const gchar *key)
+gint
+ghb_settings_get_combo_index(GValue *settings, const gchar *key)
{
- const setting_value_t* value;
- g_debug("ghb_settings_get_short_opt () key (%s)\n", key);
- value = ghb_settings_get(settings, key);
- if (value == NULL) return "";
- g_debug("shrot option: (%s)\n", value->shortOpt);
- return value->shortOpt;
+ const GValue* value;
+ value = ghb_settings_get_value(settings, key);
+ if (value == NULL) return 0;
+ ghb_combodata_t *cd;
+ if (G_VALUE_TYPE(value) != ghb_combodata_get_type())
+ return 0;
+ cd = g_value_get_boxed(value);
+ return cd->index;
}
-static void
-copy_key_val(gpointer key, gpointer val, gpointer settings)
+gchar*
+ghb_settings_get_combo_option(GValue *settings, const gchar *key)
{
- g_hash_table_insert((GHashTable*)settings,
- g_strdup((gchar*)key),
- copy_settings_value((setting_value_t*)val));
+ const GValue* value;
+ value = ghb_settings_get_value(settings, key);
+ if (value == NULL) return g_strdup("");
+ ghb_combodata_t *cd;
+ if (G_VALUE_TYPE(value) != ghb_combodata_get_type())
+ return g_strdup("");
+ cd = g_value_get_boxed(value);
+ return g_strdup(cd->option);
}
-GHashTable*
-ghb_settings_dup(GHashTable *settings)
+gchar*
+ghb_settings_get_combo_string(GValue *settings, const gchar *key)
{
- GHashTable *dup_settings;
-
- if (settings == NULL) return NULL;
- dup_settings = ghb_settings_new();
- g_hash_table_foreach (settings, copy_key_val, dup_settings);
- return dup_settings;
+ const GValue* value;
+ value = ghb_settings_get_value(settings, key);
+ if (value == NULL) return g_strdup("");
+ ghb_combodata_t *cd;
+ if (G_VALUE_TYPE(value) != ghb_combodata_get_type())
+ return g_strdup("");
+ cd = g_value_get_boxed(value);
+ return g_strdup(cd->svalue);
}
// Map widget names to setting keys
@@ -301,10 +230,10 @@ get_setting_key(GtkWidget *widget)
return name;
}
-setting_value_t*
+GValue*
ghb_widget_value(GtkWidget *widget)
{
- setting_value_t *value;
+ GValue *value = NULL;
const gchar *name;
GType type;
@@ -313,7 +242,6 @@ ghb_widget_value(GtkWidget *widget)
g_debug("NULL widget\n");
return NULL;
}
- value = g_malloc(sizeof(setting_value_t));
type = GTK_WIDGET_TYPE(widget);
if (GTK_IS_ACTION(widget))
@@ -323,209 +251,113 @@ ghb_widget_value(GtkWidget *widget)
g_debug("ghb_widget_value widget (%s)\n", name);
if (type == GTK_TYPE_ENTRY)
{
- const gchar *str = gtk_entry_get_text((GtkEntry*)widget);
- value->option = g_strdup(str);
- value->shortOpt = g_strdup(str);
- value->svalue = g_strdup(str);
- value->dvalue = g_strtod(str, NULL);
- value->ivalue = value->dvalue;
- value->index = 0;
+ const gchar *str = gtk_entry_get_text(GTK_ENTRY(widget));
+ value = ghb_string_value_new(str);
}
else if (type == GTK_TYPE_RADIO_BUTTON)
{
g_debug("\tradio_button");
- value->index = 0;
- if (gtk_toggle_button_get_active((GtkToggleButton*)widget))
- {
- g_debug("\tenable");
- value->option = g_strdup("enable");
- value->shortOpt = g_strdup("enable");
- value->svalue = g_strdup("1");
- value->ivalue = 1;
- value->dvalue = 1;
- }
- else
- {
- g_debug("\tdisable");
- value->option = g_strdup("disable");
- value->shortOpt = g_strdup("disable");
- value->svalue = g_strdup("0");
- value->ivalue = 0;
- value->dvalue = 0;
- }
+ gboolean bval;
+ bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ value = ghb_boolean_value_new(bval);
}
else if (type == GTK_TYPE_CHECK_BUTTON)
{
g_debug("\tcheck_button");
- value->index = 0;
- if (gtk_toggle_button_get_active((GtkToggleButton*)widget))
- {
- g_debug("\tenable");
- value->option = g_strdup("enable");
- value->shortOpt = g_strdup("enable");
- value->svalue = g_strdup("1");
- value->ivalue = 1;
- value->dvalue = 1;
- }
- else
- {
- g_debug("\tdisable");
- value->option = g_strdup("disable");
- value->shortOpt = g_strdup("disable");
- value->svalue = g_strdup("0");
- value->ivalue = 0;
- value->dvalue = 0;
- }
+ gboolean bval;
+ bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ value = ghb_boolean_value_new(bval);
}
else if (type == GTK_TYPE_TOGGLE_ACTION)
{
g_debug("\ttoggle action");
- value->index = 0;
- if (gtk_toggle_action_get_active((GtkToggleAction*)widget))
- {
- g_debug("\tenable");
- value->option = g_strdup("enable");
- value->shortOpt = g_strdup("enable");
- value->svalue = g_strdup("1");
- value->ivalue = 1;
- value->dvalue = 1;
- }
- else
- {
- g_debug("\tdisable");
- value->option = g_strdup("disable");
- value->shortOpt = g_strdup("disable");
- value->svalue = g_strdup("0");
- value->ivalue = 0;
- value->dvalue = 0;
- }
+ gboolean bval;
+ bval = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget));
+ value = ghb_boolean_value_new(bval);
}
else if (type == GTK_TYPE_CHECK_MENU_ITEM)
{
g_debug("\tcheck_menu_item");
- value->index = 0;
- if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
- {
- g_debug("\tenable");
- value->option = g_strdup("enable");
- value->shortOpt = g_strdup("enable");
- value->svalue = g_strdup("1");
- value->ivalue = 1;
- value->dvalue = 1;
- }
- else
- {
- g_debug("\tdisable");
- value->option = g_strdup("disable");
- value->shortOpt = g_strdup("disable");
- value->svalue = g_strdup("0");
- value->ivalue = 0;
- value->dvalue = 0;
- }
+ gboolean bval;
+ bval = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+ value = ghb_boolean_value_new(bval);
}
else if (type == GTK_TYPE_COMBO_BOX)
{
+ g_debug("\tcombo_box");
GtkTreeModel *store;
GtkTreeIter iter;
gchar *shortOpt, *option, *svalue;
- gint ivalue;
- gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+ gint index, ivalue;
+ index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
{
gtk_tree_model_get(store, &iter, 0, &option, 2, &shortOpt,
3, &ivalue, 4, &svalue, -1);
-
- value->option = option;
- value->shortOpt = shortOpt;
- value->svalue = svalue;
- value->index = index;
- value->ivalue = ivalue;
- value->dvalue = ivalue;
+ value = ghb_combo_value_new(index, option, shortOpt,
+ svalue, ivalue);
}
else
{
- value->option = g_strdup("");
- value->shortOpt = g_strdup("");
- value->svalue = g_strdup("");
- value->index = -1;
- value->ivalue = 0;
- value->dvalue = 0;
+ value = ghb_combo_value_new(-1, "", "", "", 0);
}
+ g_debug("\tdone");
}
else if (type == GTK_TYPE_COMBO_BOX_ENTRY)
{
GtkTreeModel *store;
GtkTreeIter iter;
gchar *shortOpt, *option, *svalue;
- gint ivalue;
- gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+ gint index, ivalue;
+ index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
{
gtk_tree_model_get(store, &iter, 0, &option, 2, &shortOpt,
3, &ivalue, 4, &svalue, -1);
-
- value->option = option;
- value->shortOpt = shortOpt;
- value->svalue = svalue;
- value->index = index;
- value->ivalue = ivalue;
- value->dvalue = ivalue;
+ value = ghb_combo_value_new(index, option, shortOpt,
+ svalue, ivalue);
}
else
{
- const gchar *str = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
+ const gchar *str;
+ str = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
if (str == NULL) str = "";
- value->option = g_strdup(str);
- value->shortOpt = g_strdup(str);
- value->svalue = g_strdup(str);
- value->index = -1;
- value->ivalue = -1;
- value->dvalue = 0;
+ value = ghb_combo_value_new(-1, str, str, str, -1);
}
}
else if (type == GTK_TYPE_SPIN_BUTTON)
{
- value->index = 0;
- value->dvalue = gtk_spin_button_get_value_as_int((GtkSpinButton*)widget);
- value->option = g_strdup_printf("%.8g", value->dvalue);
- value->shortOpt = g_strdup_printf("%.8g", value->dvalue);
- value->svalue = g_strdup_printf("%.8g", value->dvalue);
- value->ivalue = value->dvalue;
+ gint ival;
+ ival = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ value = ghb_int64_value_new(ival);
}
else if (type == GTK_TYPE_HSCALE)
{
- value->index = 0;
- value->dvalue = gtk_range_get_value((GtkRange*)widget);
- value->option = g_strdup_printf("%.8g", value->dvalue);
- value->shortOpt = g_strdup_printf("%.8g", value->dvalue);
- value->svalue = g_strdup_printf("%.8g", value->dvalue);
- value->ivalue = value->dvalue;
+ gdouble dval;
+ dval = gtk_range_get_value(GTK_RANGE(widget));
+ value = ghb_double_value_new(dval);
}
else if (type == GTK_TYPE_TEXT_VIEW)
{
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ GtkTextBuffer *buffer;
GtkTextIter start, end;
+ gchar *str;
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
gtk_text_buffer_get_bounds(buffer, &start, &end);
- value->svalue = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
- value->option = g_strdup(value->svalue);
- value->shortOpt = g_strdup(value->svalue);
- value->ivalue = 0;
- value->dvalue = 0;
- value->index = 0;
+ str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
+ value = ghb_string_value_new(str);
+ g_free(str);
}
else if (type == GTK_TYPE_LABEL)
{
- value->index = 0;
- value->svalue = g_strdup(gtk_label_get_text (GTK_LABEL(widget)));
- value->dvalue = g_strtod(value->svalue, NULL);
- value->option = g_strdup(value->svalue);
- value->shortOpt = g_strdup(value->svalue);
- value->ivalue = value->dvalue;
- g_debug("label (%s)\n", value->shortOpt);
+ const gchar *str;
+ str = gtk_label_get_text (GTK_LABEL(widget));
+ value = ghb_string_value_new(str);
}
else
{
@@ -537,168 +369,129 @@ ghb_widget_value(GtkWidget *widget)
}
gchar*
-ghb_widget_option(GtkWidget *widget)
-{
- setting_value_t *value;
- gchar *str = NULL;
-
- g_debug("ghb_widget_option ()\n");
- value = ghb_widget_value(widget);
- if (value != NULL)
- {
- str = g_strdup(value->option);
- ghb_free_setting_value (value);
- }
- return str;
-}
-
-gchar*
-ghb_widget_short_opt(GtkWidget *widget)
+ghb_widget_string(GtkWidget *widget)
{
- setting_value_t *value;
- gchar *str = NULL;
+ GValue *value;
+ gchar *sval;
- g_debug("ghb_widget_short_opt ()\n");
value = ghb_widget_value(widget);
- if (value != NULL)
- {
- str = g_strdup(value->shortOpt);
- ghb_free_setting_value (value);
- }
- return str;
+ sval = ghb_value_string(value);
+ ghb_value_free(value);
+ return sval;
}
-gchar*
-ghb_widget_string(GtkWidget *widget)
+gdouble
+ghb_widget_double(GtkWidget *widget)
{
- setting_value_t *value;
- gchar *str = NULL;
+ GValue *value;
+ gdouble dval;
- g_debug("ghb_widget_string ()\n");
value = ghb_widget_value(widget);
- if (value != NULL)
- {
- g_debug("str (%s)\n", value->svalue);
- str = g_strdup(value->svalue);
- ghb_free_setting_value (value);
- }
- return str;
+ dval = ghb_value_double(value);
+ ghb_value_free(value);
+ return dval;
}
-gdouble
-ghb_widget_dbl(GtkWidget *widget)
+gint64
+ghb_widget_int64(GtkWidget *widget)
{
- setting_value_t *value;
- gdouble dbl = 0;
+ GValue *value;
+ gint64 ival;
- g_debug("ghb_widget_dbl ()\n");
value = ghb_widget_value(widget);
- if (value != NULL)
- {
- dbl = value->dvalue;
- ghb_free_setting_value (value);
- }
- return dbl;
+ ival = ghb_value_int64(value);
+ ghb_value_free(value);
+ return ival;
}
gint
ghb_widget_int(GtkWidget *widget)
{
- setting_value_t *value;
- gint ivalue = 0;
+ GValue *value;
+ gint ival;
- g_debug("ghb_widget_int ()\n");
value = ghb_widget_value(widget);
- if (value != NULL)
- {
- ivalue = value->ivalue;
- ghb_free_setting_value (value);
- }
- return ivalue;
+ ival = (gint)ghb_value_int64(value);
+ ghb_value_free(value);
+ return ival;
}
gint
ghb_widget_index(GtkWidget *widget)
{
- setting_value_t *value;
+ GValue *value;
gint index = 0;
- g_debug("ghb_widget_index ()\n");
value = ghb_widget_value(widget);
- if (value != NULL)
- {
- index = value->index;
- ghb_free_setting_value (value);
- }
+ if (value == NULL) return 0;
+ ghb_combodata_t *cd;
+ if (G_VALUE_TYPE(value) != ghb_combodata_get_type())
+ return 0;
+ cd = g_value_get_boxed(value);
+ index = cd->index;
+ ghb_value_free(value);
return index;
}
void
-ghb_widget_to_setting(GHashTable *settings, GtkWidget *widget)
+ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
{
const gchar *key = NULL;
- setting_value_t *value;
+ GValue *value;
- g_debug("ghb_widget_to_setting ()\n");
if (widget == NULL) return;
+ g_debug("ghb_widget_to_setting");
// Find corresponding setting
key = get_setting_key(widget);
if (key == NULL) return;
value = ghb_widget_value(widget);
if (value != NULL)
{
- ghb_settings_set (settings, key, value);
+ ghb_settings_take_value(settings, key, value);
}
else
{
g_debug("No value found for %s\n", key);
}
- //dump_settings(settings);
}
static void
-update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
+update_widget(GtkWidget *widget, const GValue *value)
{
GType type;
- gchar *value;
+ gchar *str;
+ gint ival;
+ gdouble dval;
- 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)
- {
- value = g_strdup_printf ("%d", parm_ivalue);
- }
- else
- {
- value = g_strdup(parm_svalue);
- }
- g_debug("update widget value (%s)", value);
+ if (value == NULL) return;
+ str = ghb_value_string(value);
+ ival = ghb_value_int(value);
+ dval = ghb_value_double(value);
type = GTK_OBJECT_TYPE(widget);
if (type == GTK_TYPE_ENTRY)
{
g_debug("entry");
- gtk_entry_set_text((GtkEntry*)widget, value);
+ gtk_entry_set_text((GtkEntry*)widget, str);
}
else if (type == GTK_TYPE_RADIO_BUTTON)
{
g_debug("radio button");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), string_is_true(value));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
}
else if (type == GTK_TYPE_CHECK_BUTTON)
{
g_debug("check button");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), string_is_true(value));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
}
else if (type == GTK_TYPE_TOGGLE_ACTION)
{
g_debug("toggle action");
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(widget), string_is_true(value));
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(widget), ival);
}
else if (type == GTK_TYPE_CHECK_MENU_ITEM)
{
g_debug("check menu item");
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), string_is_true(value));
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), ival);
}
else if (type == GTK_TYPE_COMBO_BOX)
{
@@ -708,28 +501,36 @@ update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
gint ivalue;
gboolean foundit = FALSE;
- g_debug("combo (%s)", value);
+ g_debug("combo (%s)", str);
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 (parm_svalue == NULL && ivalue == parm_ivalue)
+ gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
+ if (strcmp(shortOpt, str) == 0)
{
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
+ gtk_combo_box_set_active_iter (
+ GTK_COMBO_BOX(widget), &iter);
g_free(shortOpt);
foundit = TRUE;
break;
}
- else if (strcmp(shortOpt, value) == 0)
+ g_free(shortOpt);
+ } while (gtk_tree_model_iter_next (store, &iter));
+ }
+ if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
+ {
+ do
+ {
+ gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
+ if (ivalue == ival)
{
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
- g_free(shortOpt);
+ gtk_combo_box_set_active_iter (
+ GTK_COMBO_BOX(widget), &iter);
foundit = TRUE;
break;
}
- g_free(shortOpt);
} while (gtk_tree_model_iter_next (store, &iter));
}
if (!foundit)
@@ -751,22 +552,30 @@ update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
{
do
{
- gtk_tree_model_get(store, &iter, 2, &shortOpt, 3, &ivalue, -1);
- if (parm_svalue == NULL && ivalue == parm_ivalue)
+ gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
+ if (strcmp(shortOpt, str) == 0)
{
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
+ gtk_combo_box_set_active_iter (
+ GTK_COMBO_BOX(widget), &iter);
g_free(shortOpt);
foundit = TRUE;
break;
}
- else if (strcmp(shortOpt, value) == 0)
+ g_free(shortOpt);
+ } while (gtk_tree_model_iter_next (store, &iter));
+ }
+ if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
+ {
+ do
+ {
+ gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
+ if (ivalue == ival)
{
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
- g_free(shortOpt);
+ gtk_combo_box_set_active_iter (
+ GTK_COMBO_BOX(widget), &iter);
foundit = TRUE;
break;
}
- g_free(shortOpt);
} while (gtk_tree_model_iter_next (store, &iter));
}
if (!foundit)
@@ -774,880 +583,54 @@ update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget)));
if (entry)
{
- gtk_entry_set_text (entry, value);
+ gtk_entry_set_text (entry, str);
}
}
}
else if (type == GTK_TYPE_SPIN_BUTTON)
{
- gdouble val;
-
- g_debug("spin (%s)", value);
- val = g_strtod(value, NULL);
- gtk_spin_button_set_value((GtkSpinButton*)widget, val);
+ g_debug("spin (%s)", str);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), dval);
}
else if (type == GTK_TYPE_HSCALE)
{
- gdouble val;
-
g_debug("hscale");
- val = g_strtod(value, NULL);
- gtk_range_set_value((GtkRange*)widget, val);
+ gtk_range_set_value(GTK_RANGE(widget), dval);
}
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);
+ g_debug("textview (%s)", str);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(
+ GTK_TEXT_VIEW(widget));
+ gtk_text_buffer_set_text (buffer, str, -1);
}
else
{
g_debug("Attempt to set unknown widget type");
}
- g_free(value);
-}
-
-int
-ghb_ui_update(signal_user_data_t *ud, const gchar *name, const gchar *value)
-{
- GObject *object;
-
- g_debug("ghb_ui_update ()\n");
- object = GHB_OBJECT(ud->builder, name);
- if (object == NULL)
- {
- g_debug("Failed to find widget for key: %s\n", name);
- return -1;
- }
- update_widget((GtkWidget*)object, value, 0);
- // 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, (GtkWidget*)object);
- return 0;
+ g_free(str);
}
int
-ghb_ui_update_int(signal_user_data_t *ud, const gchar *name, gint ivalue)
+ghb_ui_update(signal_user_data_t *ud, const gchar *name, const GValue *value)
{
GObject *object;
- g_debug("ghb_ui_update_int ()\n");
+ if (name == NULL || value == NULL)
+ return 0;
object = GHB_OBJECT(ud->builder, name);
if (object == NULL)
{
g_debug("Failed to find widget for key: %s\n", name);
return -1;
}
- update_widget((GtkWidget*)object, NULL, ivalue);
+ update_widget((GtkWidget*)object, value);
// 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, (GtkWidget*)object);
return 0;
}
-static void
-show_setting(gpointer key, gpointer value, gpointer user_data)
-{
- printf("key (%s) -- value (%s)\n", (gchar*)key, (gchar*)value);
-}
-
-void
-dump_settings(GHashTable *settings)
-{
- printf("------------------------------------\n");
- g_hash_table_foreach(settings, show_setting, NULL);
-}
-
-// This is a bit hackish, but effective
-const gchar defaultSettings[] =
-#include "internal_defaults.h"
-;
-const gchar standardPresets[] =
-#include "standard_presets.h"
-;
-
-typedef struct
-{
- gchar *name;
- gchar *description;
- gboolean custom;
- gboolean defalt;
- GKeyFile *keyFile;
-} presets_data_t;
-
-static GKeyFile *presetsKeyFile;
-static GKeyFile *internalKeyFile;
-static GKeyFile *prefsKeyFile;
-static GList *presetsList;
-
-presets_data_t *
-presets_list_search(GList *list, const gchar *name)
-{
- GList *link = list;
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- g_debug("search -- %s\n", data->name);
- if (strcmp(name, data->name) == 0)
- {
- return data;
- }
- link = g_list_next(link);
- }
- return NULL;
-}
-
-void
-ghb_set_preset_default(GHashTable *settings)
-{
- const gchar *preset;
- presets_data_t *data;
-
- preset = ghb_settings_get_string (settings, "default_preset");
- data = presets_list_search(presetsList, preset);
- if (data != NULL)
- {
- data->defalt = FALSE;
- }
- preset = ghb_settings_get_string (settings, "preset");
- data = presets_list_search(presetsList, preset);
- if (data != NULL)
- {
- data->defalt = TRUE;
- }
- ghb_settings_set_string(settings, "default_preset", preset);
- ghb_prefs_save(settings);
-}
-
-gint
-ghb_presets_list_index(const gchar *name)
-{
- GList *link = presetsList;
- int ii = 0;
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- if (strcmp(name, data->name) == 0)
- {
- return ii;
- }
- link = g_list_next(link);
- ii++;
- }
- return -1;
-}
-
-gint
-ghb_preset_flags(const gchar *name, gint *index)
-{
- GList *link = presetsList;
- int ii = 0;
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- if (strcmp(name, data->name) == 0)
- {
- gint ret = 0;
-
- *index = ii;
- ret = (data->custom ? PRESET_CUSTOM : 0);
- ret |= (data->defalt ? PRESET_DEFAULT : 0);
- return ret;
- }
- link = g_list_next(link);
- ii++;
- }
- *index = -1;
- return 0;
-}
-
-gchar**
-ghb_presets_get_names()
-{
- gchar **result;
- GList *link = presetsList;
- int ii = 0;
-
- g_debug("ghb_presets_get_names()\n");
- result = g_malloc((g_list_length(presetsList)+1) * sizeof(gchar*));
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- result[ii++] = g_strdup(data->name);
- link = g_list_next(link);
- }
- result[ii] = NULL;
- return result;
-}
-
-gchar**
-ghb_presets_get_descriptions()
-{
- gchar **result;
- GList *link = presetsList;
- int ii = 0;
-
- g_debug("ghb_presets_get_names()\n");
- result = g_malloc((g_list_length(presetsList)+1) * sizeof(gchar*));
- while (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- result[ii++] = g_strdup(data->description);
- link = g_list_next(link);
- }
- result[ii] = NULL;
- return result;
-}
-
-const gchar*
-ghb_presets_get_name(gint index)
-{
- gchar *result = NULL;
- GList *link = presetsList;
- int ii = 0;
-
- g_debug("ghb_presets_get_name()\n");
- while ((link != NULL) && (ii < index))
- {
- link = g_list_next(link);
- ii++;
- }
- if (link != NULL)
- {
- presets_data_t *data;
- data = (presets_data_t*)link->data;
- result = data->name;
- }
- return result;
-}
-
-static gchar*
-preset_get_string(
- GKeyFile *keyFile,
- const gchar *name,
- const gchar *key)
-{
- gchar *str;
-
- g_debug("preset (%s) key (%s)\n", name, key);
- str = NULL;
- if (name != NULL && keyFile != NULL)
- {
- str = g_key_file_get_string(keyFile, name, key, NULL);
- g_debug("(%s, %s)\n", key, str);
- }
- if (str == NULL)
- {
- str = g_key_file_get_string(internalKeyFile, "Presets", key, NULL);
- }
- return str;
-}
-
-static gboolean
-init_presets_hash_from_key_file(signal_user_data_t *ud, const gchar *name, GKeyFile *keyFile)
-{
- gchar **keys;
- gsize length;
- gchar *str;
-
- // Get key list from internal default presets. This way we do not
- // load any unknown keys.
- keys = g_key_file_get_keys(internalKeyFile, "Presets", &length, NULL);
- if (keys != NULL)
- {
- gint ii;
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- g_debug("key (%s)\n", keys[ii]);
- str = preset_get_string(keyFile, name, keys[ii]);
- if (str != NULL)
- {
- g_debug("name (%s): key (%s) -- str (%s)\n", name, keys[ii], str);
- ghb_settings_set_string(ud->settings, keys[ii], str);
- ghb_ui_update(ud, keys[ii], str);
- g_free(str);
- }
- }
- g_strfreev(keys);
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-preset_to_ui(signal_user_data_t *ud, presets_data_t *data)
-{
- g_debug("preset_to_settings()\n");
- // Initialize the ui from presets file.
- if (data == NULL)
- {
- // Set defaults
- init_presets_hash_from_key_file(ud, NULL, NULL);
- return;
- }
- else
- {
- g_debug("preset name (%s)\n", data->name);
- // Initialize from preset
- init_presets_hash_from_key_file(ud, data->name, data->keyFile);
- }
- if (ghb_settings_get_bool(ud->settings, "allow_tweaks"))
- {
- gchar *str;
- str = preset_get_string(data->keyFile, data->name, "deinterlace");
- if (str)
- {
- ghb_ui_update(ud, "tweak_deinterlace", str);
- g_free(str);
- }
- str = preset_get_string(data->keyFile, data->name, "denoise");
- if (str)
- {
- ghb_ui_update(ud, "tweak_denoise", str);
- g_free(str);
- }
- }
-}
-
-static void
-preset_update_ui(signal_user_data_t *ud, presets_data_t *data, const gchar *key)
-{
- gchar *str;
-
- g_debug("preset_update_settings()\n");
- // Initialize the ui from presets file.
- if (data == NULL) return;
- str = g_key_file_get_string(data->keyFile, data->name, key, NULL);
- if (str == NULL)
- {
- str = g_key_file_get_string(internalKeyFile, "Presets", key, NULL);
- }
- if (str != NULL)
- {
- ghb_ui_update(ud, key, str);
- g_free(str);
- }
-}
-
-void
-ghb_set_preset(signal_user_data_t *ud, const gchar *name)
-{
- presets_data_t *data;
-
- g_debug("ghb_set_preset() %s\n", name);
- if (name == NULL)
- {
- name = ghb_presets_get_name(0);
- }
- if (name == NULL)
- {
- preset_to_ui(ud, NULL);
- }
- else
- {
- data = presets_list_search(presetsList, name);
- preset_to_ui(ud, data);
- ghb_settings_set_string(ud->settings, "preset", name);
- }
- ghb_pref_audio_init(ud);
-}
-
-void
-ghb_update_from_preset(
- signal_user_data_t *ud,
- const gchar *name,
- const gchar *key)
-{
- presets_data_t *data;
-
- g_debug("ghb_update_from_preset() %s %s\n", name, key);
- if (name == NULL) return;
- data = presets_list_search(presetsList, name);
- preset_update_ui(ud, data, key);
-}
-
-static void
-build_presets_list(GHashTable *settings)
-{
- GList *link = presetsList;
- presets_data_t *data;
- gchar **presets;
- gsize length;
- gint ii;
-
- g_debug("build_presets_list ()\n");
- // First clear out the old presets list
- while (link != NULL)
- {
- data = (presets_data_t*)link->data;
- g_free(data->name);
- if (data->description != NULL)
- g_free(data->description);
- g_free(data);
- link = g_list_delete_link (link, link);
- }
- presetsList = NULL;
-
- // Now build up the new list
- // Make standard presets appear before custom in the list
- const gchar *def_name = ghb_settings_get_string(settings, "default_preset");
- presets = g_key_file_get_groups(presetsKeyFile, &length);
- if (length <= 0) return;
- for (ii = 0; ii < length; ii++)
- {
- gint type;
- GError *err = NULL;
- type = g_key_file_get_integer(presetsKeyFile, presets[ii], "preset_type", &err);
- if (!err && type == 0)
- { // Its a standard preset
- gchar *desc;
- data = g_malloc(sizeof(presets_data_t));
- data->name = g_strdup(presets[ii]);
- data->keyFile = presetsKeyFile;
- data->custom = FALSE;
- data->defalt = FALSE;
- if ((def_name != NULL) && (strcmp(def_name, data->name) == 0))
- {
- data->defalt = TRUE;
- }
- desc = g_key_file_get_string(presetsKeyFile, presets[ii], "preset_description", NULL);
- data->description = desc;
- presetsList = g_list_append(presetsList, data);
- }
- }
- for (ii = 0; ii < length; ii++)
- {
- gint type;
- GError *err = NULL;
- type = g_key_file_get_integer(presetsKeyFile, presets[ii], "preset_type", &err);
- if (err || type != 0)
- { // Its a custom preset
- gchar *desc;
- data = g_malloc(sizeof(presets_data_t));
- data->name = g_strdup(presets[ii]);
- data->keyFile = presetsKeyFile;
- data->custom = TRUE;
- data->defalt = FALSE;
- if ((def_name != NULL) && (strcmp(def_name, data->name) == 0))
- {
- data->defalt = TRUE;
- }
- desc = g_key_file_get_string(presetsKeyFile, presets[ii], "preset_description", NULL);
- data->description = desc;
- presetsList = g_list_append(presetsList, data);
- }
- }
- g_strfreev(presets);
-}
-
-static void
-store_key_file(GKeyFile *key_file, const gchar *name)
-{
- gchar *settingsString;
- const gchar *dir;
- gsize length;
- gchar *config;
- gint fd;
-
- g_debug("store_key_file ()\n");
- settingsString = g_key_file_to_data(key_file, &length, NULL);
-
- dir = g_get_user_config_dir();
- config = g_strdup_printf ("%s/ghb", dir);
- if (!g_file_test(config, G_FILE_TEST_IS_DIR))
- {
- g_mkdir (config, 0755);
- }
- g_free(config);
- config = g_strdup_printf ("%s/ghb/%s", dir, name);
- fd = g_open(config, O_RDWR|O_CREAT|O_TRUNC, 0777);
- write(fd, settingsString, length);
- close(fd);
- g_debug("prefs:\n%s\n", settingsString);
- g_free(settingsString);
-}
-
-void
-ghb_prefs_to_ui(signal_user_data_t *ud)
-{
- const gchar *str;
-
- str = ghb_settings_get_string(ud->settings, "default_source");
- ghb_settings_set_string (ud->settings, "source", str);
- str = ghb_settings_get_string(ud->settings, "destination_dir");
-
- gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
- ghb_ui_update(ud, "destination", path);
- g_free(path);
-}
-
-static gboolean prefs_initializing = FALSE;
-
-void
-ghb_prefs_save(GHashTable *settings)
-{
- gint ii;
- const gchar *value;
- gchar **keys;
- gsize length;
-
- if (prefs_initializing) return;
- keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
- if (keys != NULL)
- {
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- value = ghb_settings_get_string(settings, keys[ii]);
- if (value != NULL)
- {
- g_key_file_set_value(prefsKeyFile, "Preferences", keys[ii], value);
- }
- }
- g_strfreev(keys);
- store_key_file(prefsKeyFile, "preferences");
- }
-}
-
-void
-ghb_pref_save(GHashTable *settings, const gchar *key)
-{
- const gchar *value;
-
- if (prefs_initializing) return;
- value = ghb_settings_get_string(settings, key);
- if (value != NULL)
- {
- g_key_file_set_value(prefsKeyFile, "Preferences", key, value);
- store_key_file(prefsKeyFile, "preferences");
- }
-}
-
-#if 0
-static void
-dump_key_file(GKeyFile *keyFile, const gchar *section)
-{
- gint ii;
- gchar **keys;
- gsize length;
-
- // Get defaults from internal defaults
- keys = g_key_file_get_keys(keyFile, section, &length, NULL);
- if (keys != NULL)
- {
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- gchar *str;
-
- str = g_key_file_get_string(keyFile, section, keys[ii], NULL);
- if (str != NULL)
- {
- g_message("Preference: key (%s) -- str (%s)\n", keys[ii], str);
- g_free(str);
- }
- else
- {
- g_message("Preference: key (%s) -- str **none**\n", keys[ii]);
- }
- }
- g_strfreev(keys);
- }
- else
- {
- g_message("no keys");
- }
-}
-#endif
-
-void
-ghb_prefs_load(signal_user_data_t *ud)
-{
- gint ii;
- const gchar *dir;
- gchar *config;
- gchar *value;
- gchar **keys;
- gsize length;
- gboolean res;
-
- prefs_initializing = TRUE;
- internalKeyFile = g_key_file_new();
- res = g_key_file_load_from_data( internalKeyFile, defaultSettings,
- sizeof(defaultSettings), G_KEY_FILE_NONE, NULL);
- if (!res)
- g_warning("Failed to initialize internal defaults\n");
-
- keys = g_key_file_get_keys(internalKeyFile, "Initialization", &length, NULL);
- if (keys != NULL)
- {
- gint ii;
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- gchar *str;
-
- g_debug("key (%s)\n", keys[ii]);
- str = g_key_file_get_string(internalKeyFile, "Initialization", keys[ii], NULL);
- if (str != NULL)
- {
- g_debug("Initialization: key (%s) -- str (%s)\n", keys[ii], str);
- ghb_settings_set_string(ud->settings, keys[ii], str);
- ghb_ui_update(ud, keys[ii], str);
- g_free(str);
- }
- }
- g_strfreev(keys);
- }
- prefsKeyFile = g_key_file_new();
- dir = g_get_user_config_dir();
- config = g_strdup_printf ("%s/ghb/preferences", dir);
- if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
- {
- g_key_file_load_from_file( prefsKeyFile, config, G_KEY_FILE_KEEP_COMMENTS, NULL);
- }
- value = g_key_file_get_value(prefsKeyFile, "Preferences", "version", NULL);
- if (value == NULL)
- {
- gint ii;
-
- // Get defaults from internal defaults
- keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
- if (keys != NULL)
- {
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- gchar *str;
-
- str = g_key_file_get_string(internalKeyFile, "Preferences", keys[ii], NULL);
- if (str != NULL)
- {
- g_debug("Preference: key (%s) -- str (%s)\n", keys[ii], str);
- g_key_file_set_value(prefsKeyFile, "Preferences", keys[ii], str);
- g_free(str);
- }
- }
- g_strfreev(keys);
- }
- const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
- g_key_file_set_value(prefsKeyFile, "Preferences", "destination_dir", dir);
- store_key_file(prefsKeyFile, "preferences");
- }
- g_free(config);
- keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
- if (keys != NULL)
- {
- for (ii = 0; keys[ii] != NULL; ii++)
- {
- value = g_key_file_get_value(prefsKeyFile, "Preferences", keys[ii], NULL);
- if (value != NULL)
- {
- ghb_settings_set_string(ud->settings, keys[ii], value);
- ghb_ui_update(ud, keys[ii], value);
- g_free(value);
- }
- else
- {
- value = g_key_file_get_value(internalKeyFile, "Preferences", keys[ii], NULL);
- if (value != NULL)
- {
- ghb_settings_set_string(ud->settings, keys[ii], value);
- ghb_ui_update(ud, keys[ii], value);
- g_free(value);
- }
- }
- }
- g_strfreev(keys);
- }
- gint bval = ghb_settings_get_int(ud->settings, "show_presets");
- ghb_ui_update_int(ud, "show_presets", bval);
- if (ghb_settings_get_bool(ud->settings, "hbfd_feature"))
- {
- GtkAction *action;
- bval = ghb_settings_get_int(ud->settings, "hbfd");
- ghb_ui_update_int(ud, "hbfd", bval);
- action = GHB_ACTION (ud->builder, "hbfd");
- gtk_action_set_visible(action, TRUE);
- }
- else
- {
- ghb_ui_update_int(ud, "hbfd", 0);
- }
- prefs_initializing = FALSE;
-}
-
-void
-ghb_presets_reload(signal_user_data_t *ud)
-{
- GKeyFile *keyFile;
-
- g_debug("ghb_presets_reload()\n");
- keyFile = g_key_file_new();
- g_key_file_load_from_data( keyFile, standardPresets,
- sizeof(standardPresets), G_KEY_FILE_NONE, NULL);
-
- gchar **groups, **keys;
- gchar *value;
- gint ii, jj;
-
- // Merge the keyfile contents into our presets
- groups = g_key_file_get_groups(keyFile, NULL);
- // First remove any existing groups with the same names
- for (ii = 0; groups[ii] != NULL; ii++)
- {
- g_key_file_remove_group(presetsKeyFile, groups[ii], NULL);
- }
- for (ii = 0; groups[ii] != NULL; ii++)
- {
- keys = g_key_file_get_keys(keyFile, groups[ii], NULL, NULL);
- for (jj = 0; keys[jj] != NULL; jj++)
- {
- GError *err = NULL;
- value = g_key_file_get_string(
- keyFile, groups[ii], keys[jj], &err);
- if (value && !err)
- {
- g_key_file_set_string(
- presetsKeyFile, groups[ii], keys[jj], value);
- }
- if (value) g_free(value);
- }
- g_strfreev(keys);
- }
- g_strfreev(groups);
- g_key_file_free(keyFile);
- store_key_file(presetsKeyFile, "presets");
- build_presets_list(ud->settings);
-}
-
-void
-ghb_presets_load(signal_user_data_t *ud)
-{
- const gchar *dir;
- gchar *config;
-
- g_debug("ghb_presets_load()\n");
- presetsKeyFile = g_key_file_new();
- dir = g_get_user_config_dir();
- config = g_strdup_printf ("%s/ghb/presets", dir);
-
- if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
- {
- g_key_file_load_from_file( presetsKeyFile, config,
- G_KEY_FILE_KEEP_COMMENTS, NULL);
- }
- else
- {
- g_key_file_load_from_data( presetsKeyFile, standardPresets,
- sizeof(standardPresets), G_KEY_FILE_NONE, NULL);
- }
- g_free(config);
- build_presets_list(ud->settings);
-}
-
-static void
-presets_store()
-{
- g_debug("presets_store ()\n");
- store_key_file(presetsKeyFile, "presets");
-}
-
-typedef struct
-{
- const gchar *name;
- GKeyFile *keyFile;
- gboolean autoscale;
-} store_key_info_t;
-
-static void
-store_to_key_file(gpointer xkey, gpointer xvalue, gpointer xski)
-{
- store_key_info_t *ski = (store_key_info_t*)xski;
- setting_value_t *value = (setting_value_t *)xvalue;
- gchar *key = (gchar*)xkey;
- gchar *str;
-
- if (!ski->autoscale)
- {
- if (strcmp(key, "scale_width"))
- {
- key = "max_width";
- }
- if (strcmp(key, "scale_height"))
- {
- key = "max_height";
- }
- }
- str = g_key_file_get_string(internalKeyFile, "Presets", key, NULL);
- if (str == NULL)
- {
- g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
- return;
- }
- g_debug("comparing: key (%s) -- (%s) == (%s)\n", (gchar*)key, str, value->svalue);
- if (strcmp(str, value->shortOpt) != 0)
- {
- // Differs from default value. Store it.
- g_debug("storing: key (%s) -- (%s)\n", (gchar*)key, value->shortOpt);
- gchar *tmp = g_strescape (value->shortOpt, NULL);
- g_key_file_set_value(ski->keyFile, ski->name, (gchar*)key, tmp);
- g_free(tmp);
- }
- else
- {
- // Remove it if it exists already in keyfile
- g_key_file_remove_key (ski->keyFile, ski->name, (gchar*)key, NULL);
- }
- g_free(str);
-}
-
-void
-ghb_settings_save(signal_user_data_t *ud, const gchar *name)
-{
- store_key_info_t ski;
-
- g_debug("ghb_settings_save ()\n");
- ski.name = name;
- ski.keyFile = presetsKeyFile;
- if (ghb_settings_get_bool(ud->settings, "allow_tweaks"))
- {
- const gchar *str;
- str = ghb_settings_get_short_opt(ud->settings, "tweak_deinterlace");
- if (str)
- ghb_settings_set_string(ud->settings, "deinterlace", str);
- str = ghb_settings_get_short_opt(ud->settings, "tweak_denoise");
- if (str)
- ghb_settings_set_string(ud->settings, "denoise", str);
- }
- ski.autoscale = ghb_settings_get_bool (ud->settings, "autoscale");
- g_key_file_remove_group(presetsKeyFile, name, NULL);
- ghb_settings_set_string(ud->settings, "preset_type", "1");
- g_hash_table_foreach(ud->settings, store_to_key_file, &ski);
- presets_store();
- build_presets_list(ud->settings);
- ud->dont_clear_presets = TRUE;
- ghb_set_preset (ud, name);
- ud->dont_clear_presets = FALSE;
-}
-
-// Return false if attempt is made.
-gboolean
-ghb_presets_remove(GHashTable *settings, const gchar *name)
-{
- g_debug("ghb_presets_remove()\n");
- if (g_key_file_has_group(presetsKeyFile, name))
- {
- g_debug("\t removing %s\n", name);
- g_key_file_remove_group(presetsKeyFile, name, NULL);
- presets_store();
- build_presets_list(settings);
- return TRUE;
- }
- return FALSE;
-}
-
enum
{
X264_OPT_DEBLOCK,
@@ -1737,21 +720,40 @@ x264_opt_get_default(const gchar *opt)
static void
x264_update_int(signal_user_data_t *ud, const gchar *name, const gchar *val)
{
- gdouble dvalue;
- gchar *end;
+ gint ival;
if (val == NULL) return;
- dvalue = g_strtod (val, &end);
- ghb_ui_update_int(ud, name, dvalue);
+ 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, "1");
+ ghb_ui_update(ud, name, ghb_boolean_value(1));
else
- ghb_ui_update(ud, name, val);
+ ghb_ui_update(ud, name, ghb_boolean_value(str_is_true(val)));
}
static void
@@ -1837,8 +839,8 @@ x264_update_deblock(signal_user_data_t *ud, const gchar *xval)
}
}
g_free(val);
- ghb_ui_update_int(ud, "x264_deblock_alpha", avalue);
- ghb_ui_update_int(ud, "x264_deblock_beta", bvalue);
+ ghb_ui_update(ud, "x264_deblock_alpha", ghb_int64_value(avalue));
+ ghb_ui_update(ud, "x264_deblock_beta", ghb_int64_value(bvalue));
}
void
@@ -1920,11 +922,13 @@ ghb_x264_parse_options(signal_user_data_t *ud, const gchar *options)
gchar*
get_deblock_val(signal_user_data_t *ud)
{
- const gchar *alpha, *beta;
+ 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;
}
@@ -1951,14 +955,18 @@ ghb_x264_opt_update(signal_user_data_t *ud, GtkWidget *widget)
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);
+ gchar *options;
+ gchar **split = NULL;
gint ii;
gboolean foundit = FALSE;
- if (split == NULL) return;
- for (ii = 0; split[ii] != NULL; ii++)
+ 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;
@@ -1976,7 +984,22 @@ ghb_x264_opt_update(signal_user_data_t *ud, GtkWidget *widget)
if (type == X264_OPT_DEBLOCK)
val = get_deblock_val(ud);
else
- val = ghb_widget_string(widget);
+ {
+ 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);
@@ -1989,13 +1012,29 @@ ghb_x264_opt_update(signal_user_data_t *ud, GtkWidget *widget)
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
- val = ghb_widget_string(widget);
+ {
+ 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);
@@ -2009,7 +1048,11 @@ ghb_x264_opt_update(signal_user_data_t *ud, GtkWidget *widget)
result = g_string_free(x264opts, FALSE);
len = strlen(result);
if (len > 0) result[len - 1] = 0;
- ghb_ui_update(ud, "x264_options", result);
+ 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);
}
}
@@ -2089,12 +1132,13 @@ ghb_sanitize_x264opts(signal_user_data_t *ud, const gchar *options)
{
x264_remove_opt(split, x264_bpyramid_syns);
}
- const gchar *me = ghb_settings_get_string(ud->settings, "x264_me");
+ 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"))
+ g_free(me);
+ if (!ghb_settings_get_boolean(ud->settings, "x264_cabac"))
{
x264_remove_opt(split, x264_trellis_syns);
}
@@ -2108,6 +1152,7 @@ ghb_sanitize_x264opts(signal_user_data_t *ud, const gchar *options)
if (split[ii][0] != 0)
g_string_append_printf(x264opts, "%s:", split[ii]);
}
+ g_strfreev(split);
// strip the trailing ":"
gchar *result;
gint len;
@@ -2117,117 +1162,76 @@ ghb_sanitize_x264opts(signal_user_data_t *ud, const gchar *options)
return result;
}
-static gint pref_acodec[8];
-static gint pref_bitrate[8];
-static gint pref_rate[8];
-static gint pref_mix[8];
-static gdouble pref_drc[8];
-static gint pref_audio_count = 0;
-
-void
-ghb_pref_audio_init(signal_user_data_t *ud)
-{
- const gchar *acodec, *bitrate, *rate, *mix, *drc;
- gchar **split_acodec, **split_bitrate, **split_rate;
- gchar **split_mix, **split_drc;
-
- acodec = ghb_settings_get_string(ud->settings, "pref_audio_codec");
- bitrate = ghb_settings_get_string(ud->settings, "pref_audio_bitrate");
- rate = ghb_settings_get_string(ud->settings, "pref_audio_rate");
- mix = ghb_settings_get_string(ud->settings, "pref_audio_mix");
- drc = ghb_settings_get_string(ud->settings, "pref_audio_drc");
- split_acodec = g_strsplit(acodec, ",", 8);
- split_bitrate = g_strsplit(bitrate, ",", 8);
- split_rate = g_strsplit(rate, ",", 8);
- split_mix = g_strsplit(mix, ",", 8);
- split_drc = g_strsplit(drc, ",", 8);
- if (split_acodec == NULL)
- { // This should never happen, but just in case...
- split_acodec = g_strsplit("faac", ",", -1);
- }
- gint ii;
- for (ii = 0; split_acodec[ii]; ii++)
- {
- pref_acodec[ii] = ghb_lookup_acodec(split_acodec[ii]);
- }
- pref_audio_count = ii;
- for (ii = 0; split_bitrate && split_bitrate[ii]; ii++)
- {
- pref_bitrate[ii] = ghb_lookup_bitrate(split_bitrate[ii]);
- }
- for (ii = 0; ii < pref_audio_count; ii++)
- {
- pref_bitrate[ii] = pref_bitrate[0];
- }
- for (ii = 0; split_rate && split_rate[ii]; ii++)
- {
- pref_rate[ii] = ghb_lookup_rate(split_rate[ii]);
- }
- for (ii = 0; ii < pref_audio_count; ii++)
- {
- pref_rate[ii] = pref_rate[0];
- }
- for (ii = 0; split_mix && split_mix[ii]; ii++)
- {
- pref_mix[ii] = ghb_lookup_mix(split_mix[ii]);
- }
- for (ii = 0; ii < pref_audio_count; ii++)
- {
- pref_mix[ii] = pref_mix[0];
- }
- for (ii = 0; split_drc && split_drc[ii]; ii++)
- {
- pref_drc[ii] = ghb_lookup_drc(split_drc[ii]);
- }
- for (ii = 0; ii < pref_audio_count; ii++)
- {
- pref_drc[ii] = pref_drc[0];
- }
-}
-
gint
-ghb_pref_acount()
+ghb_pref_acount(GValue *settings)
{
- return pref_audio_count;
+ GValue *acodec;
+ acodec = ghb_settings_get_value(settings, "pref_audio_codec");
+ return ghb_array_len(acodec);
}
gint
-ghb_pref_acodec(gint index)
+ghb_pref_acodec(GValue *settings, gint index)
{
- if (index >= pref_audio_count)
+ GValue *acodec;
+ gint count;
+
+ acodec = ghb_settings_get_value(settings, "pref_audio_codec");
+ count = ghb_array_len(acodec);
+ if (index >= count)
return 0;
- return pref_acodec[index];
+ return ghb_value_int(ghb_array_get_nth(acodec, index));
}
gint
-ghb_pref_bitrate(gint index)
+ghb_pref_bitrate(GValue *settings, gint index)
{
- if (index >= pref_audio_count)
+ GValue *bitrate;
+ gint count;
+
+ bitrate = ghb_settings_get_value(settings, "pref_audio_bitrate");
+ count = ghb_array_len(bitrate);
+ if (index >= count)
return 0;
- return pref_bitrate[index];
+ return ghb_value_int(ghb_array_get_nth(bitrate, index));
}
gint
-ghb_pref_rate(gint index)
+ghb_pref_rate(GValue *settings, gint index)
{
- if (index >= pref_audio_count)
+ GValue *rate;
+ gint count;
+
+ rate = ghb_settings_get_value(settings, "pref_audio_rate");
+ count = ghb_array_len(rate);
+ if (index >= count)
return 0;
- return pref_rate[index];
+ return ghb_value_int(ghb_array_get_nth(rate, index));
}
gint
-ghb_pref_mix(gint index)
+ghb_pref_mix(GValue *settings, gint index)
{
- if (index >= pref_audio_count)
+ GValue *mix;
+ gint count;
+
+ mix = ghb_settings_get_value(settings, "pref_audio_mix");
+ count = ghb_array_len(mix);
+ if (index >= count)
return 0;
- return pref_mix[index];
+ return ghb_value_int(ghb_array_get_nth(mix, index));
}
gdouble
-ghb_pref_drc(gint index)
+ghb_pref_drc(GValue *settings, gint index)
{
- if (index >= pref_audio_count)
+ GValue *drc;
+ gint count;
+
+ drc = ghb_settings_get_value(settings, "pref_audio_drc");
+ count = ghb_array_len(drc);
+ if (index >= count)
return 0;
- return pref_drc[index];
+ return ghb_value_double(ghb_array_get_nth(drc, index));
}
diff --git a/gtk/src/settings.h b/gtk/src/settings.h
index 25b9d6310..99d8e6866 100644
--- a/gtk/src/settings.h
+++ b/gtk/src/settings.h
@@ -45,10 +45,8 @@ typedef struct
gboolean debug;
gboolean dont_clear_presets;
GtkBuilder *builder;
- GHashTable *settings;
- GSList *audio_settings;
- gchar **chapter_list;
- GSList *queue;
+ GValue *settings;
+ GValue *queue;
GIOChannel *activity_log;
} signal_user_data_t;
@@ -60,79 +58,53 @@ enum
GHB_QUEUE_DONE,
};
-typedef struct
-{
- gint unique_id;
- gint status;
- GHashTable *settings;
- GSList *audio_settings;
- gchar **chapter_list;
-} job_settings_t;
+GValue* ghb_settings_new(void);
+void ghb_settings_take_value(
+ GValue *settings, const gchar *key, GValue *value);
+void ghb_settings_set_value(
+ GValue *settings, const gchar *key, const GValue *value);
+void ghb_settings_set_string(
+ GValue *settings, const gchar *key, const gchar *sval);
+void ghb_settings_set_double(GValue *settings, const gchar *key, gdouble dval);
+void ghb_settings_set_int64(GValue *settings, const gchar *key, gint64 ival);
+void ghb_settings_set_int(GValue *settings, const gchar *key, gint ival);
+void ghb_settings_set_boolean(
+ GValue *settings, const gchar *key, gboolean bval);
+void ghb_settings_set_combo(
+ GValue *settings, const gchar *key, gint index, const gchar *option,
+ const gchar *shortOpt, const gchar *svalue, gint ivalue);
+void ghb_settings_copy(
+ GValue *settings, const gchar *key, const GValue *value);
+GValue* ghb_settings_get_value(GValue *settings, const gchar *key);
+gboolean ghb_settings_get_boolean(GValue *settings, const gchar *key);
+gint64 ghb_settings_get_int64(GValue *settings, const gchar *key);
+gint ghb_settings_get_int(GValue *settings, const gchar *key);
+gdouble ghb_settings_get_double(GValue *settings, const gchar *key);
+gchar* ghb_settings_get_string(GValue *settings, const gchar *key);
+gint ghb_settings_get_combo_index(GValue *settings, const gchar *key);
+gchar* ghb_settings_get_combo_option(GValue *settings, const gchar *name);
+gchar* ghb_settings_get_combo_string(GValue *settings, const gchar *key);
-typedef struct
-{
- gint index;
- gchar *option;
- gchar *shortOpt;
- gint ivalue;
- gdouble dvalue;
- gchar *svalue;
-} setting_value_t;
-
-GHashTable* ghb_settings_new();
-void ghb_settings_set(GHashTable *settings, const gchar *key,
- setting_value_t *value);
-void ghb_settings_set_string(GHashTable *settings, const gchar *key, const gchar *str);
-void ghb_settings_set_dbl(GHashTable *settings, const gchar *key, gdouble dvalue);
-void ghb_settings_copy(GHashTable *settings, const gchar *key, const setting_value_t *value);
-const setting_value_t* ghb_settings_get(GHashTable *settings, const gchar *key);
-gboolean ghb_settings_get_bool(GHashTable *settings, const gchar *key);
-gint ghb_settings_get_index(GHashTable *settings, const gchar *key);
-gint ghb_settings_get_int(GHashTable *settings, const gchar *key);
-gdouble ghb_settings_get_dbl(GHashTable *settings, const gchar *key);
-setting_value_t* ghb_widget_value(GtkWidget *widget);
-gchar* ghb_widget_short_opt(GtkWidget *widget);
-gchar* ghb_widget_option(GtkWidget *widget);
+GValue* ghb_widget_value(GtkWidget *widget);
gchar* ghb_widget_string(GtkWidget *widget);
+gdouble ghb_widget_double(GtkWidget *widget);
+gint64 ghb_widget_int64(GtkWidget *widget);
gint ghb_widget_int(GtkWidget *widget);
-gdouble ghb_widget_dbl(GtkWidget *widget);
gint ghb_widget_index(GtkWidget *widget);
-const gchar* ghb_settings_get_string(GHashTable *settings, const gchar *key);
-const gchar* ghb_settings_get_option(GHashTable *settings, const gchar *name);
-const gchar* ghb_settings_get_short_opt(GHashTable *settings, const gchar *key);
-GHashTable* ghb_settings_dup(GHashTable *settings);
-void ghb_widget_to_setting(GHashTable *settings, GtkWidget *widget);
-int ghb_ui_update(signal_user_data_t *ud, const gchar *key, const gchar *value);
-int ghb_ui_update_int(signal_user_data_t *ud, const gchar *key, gint ivalue);
-void ghb_settings_save(signal_user_data_t *ud, const gchar *name);
-void ghb_presets_load(signal_user_data_t *ud);
-void ghb_presets_reload(signal_user_data_t *ud);
-void ghb_set_preset(signal_user_data_t *ud, const gchar *name);
-void ghb_update_from_preset( signal_user_data_t *ud,
- const gchar *name, const gchar *key);
-gchar** ghb_presets_get_names();
-gchar** ghb_presets_get_descriptions();
-const gchar* ghb_presets_get_name(gint index);
-gboolean ghb_presets_remove(GHashTable *settings, const gchar *name);
-void ghb_presets_revert(signal_user_data_t *ud, const gchar *name);
-GdkColor* ghb_presets_color(gboolean modified);
-const gchar* ghb_presets_current_name();
-gint ghb_presets_list_index(const gchar *name);
-gint ghb_preset_flags(const gchar *name, gint *index);
-void ghb_prefs_load(signal_user_data_t *ud);
-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_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();
-gint ghb_pref_acodec(gint index);
-gint ghb_pref_bitrate(gint index);
-gint ghb_pref_rate(gint index);
-gint ghb_pref_mix(gint index);
-gdouble ghb_pref_drc(gint index);
+
+gint ghb_pref_acount(GValue *settings);
+gint ghb_pref_acodec(GValue *settings, gint index);
+gint ghb_pref_bitrate(GValue *settings, gint index);
+gint ghb_pref_rate(GValue *settings, gint index);
+gint ghb_pref_mix(GValue *settings, gint index);
+gdouble ghb_pref_drc(GValue *settings, gint index);
#endif // _SETTINGS_H_
diff --git a/gtk/src/standard_presets b/gtk/src/standard_presets
index 0a8e641f3..b57db1eb5 100755
--- a/gtk/src/standard_presets
+++ b/gtk/src/standard_presets
@@ -8,26 +8,26 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mkv
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=slower
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=1
-turbo=1
-variable_frame_rate=0
+two_pass=enable
+turbo=enable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1000
video_target_size=700
video_quality=64
@@ -42,25 +42,25 @@ pref_audio_bitrate=160,160
pref_audio_rate=48,source
pref_audio_mix=dpl2,none
pref_audio_drc=1,1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-large_mp4=1
-autoscale=1
+large_mp4=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=0
-variable_frame_rate=0
+two_pass=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=2500
video_target_size=700
video_quality=64
@@ -75,26 +75,26 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=none
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mkv
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=1
-turbo=1
-variable_frame_rate=0
+two_pass=enable
+turbo=enable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1800
video_target_size=700
video_quality=64
@@ -109,26 +109,26 @@ pref_audio_bitrate=128
pref_audio_rate=source
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-autocrop=1
-autoscale=0
+autocrop=enable
+autoscale=disable
max_width=512
max_height=0
-anamorphic=0
-keep_aspect=1
-detelecine=0
-decomb=0
+anamorphic=disable
+keep_aspect=enable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=ffmpeg
-two_pass=0
-turbo=0
-variable_frame_rate=0
+two_pass=disable
+turbo=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=512
video_target_size=700
video_quality=64
@@ -143,26 +143,26 @@ pref_audio_bitrate=128
pref_audio_rate=source
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-autocrop=1
-autoscale=0
+autocrop=enable
+autoscale=disable
max_width=640
max_height=0
-anamorphic=0
-keep_aspect=1
-detelecine=0
-decomb=0
+anamorphic=disable
+keep_aspect=enable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=1
-turbo=1
-variable_frame_rate=0
+two_pass=enable
+turbo=enable
+variable_frame_rate=disable
framerate=source
-vquality_type_target=1
+vquality_type_target=enable
video_bitrate=1600
video_target_size=695
video_quality=64
@@ -177,25 +177,25 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=0
+chapter_markers=disable
container=mp4
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=0
-keep_aspect=1
-detelecine=0
-decomb=0
+anamorphic=disable
+keep_aspect=enable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=ffmpeg
-two_pass=0
-variable_frame_rate=0
+two_pass=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1000
video_target_size=700
video_quality=64
@@ -210,26 +210,26 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=none
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mkv
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=0
-turbo=0
-variable_frame_rate=0
+two_pass=disable
+turbo=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_constant=1
+vquality_type_constant=enable
video_bitrate=2000
video_target_size=700
video_quality=64
@@ -244,26 +244,26 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=none
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mkv
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=1
-turbo=1
-variable_frame_rate=0
+two_pass=enable
+turbo=enable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1600
video_target_size=700
video_quality=64
@@ -278,26 +278,26 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=none
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mkv
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=1
-turbo=1
-variable_frame_rate=0
+two_pass=enable
+turbo=enable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1800
video_target_size=700
video_quality=64
@@ -312,26 +312,26 @@ pref_audio_bitrate=128
pref_audio_rate=48
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-ipod_file=1
-autocrop=1
-autoscale=0
+ipod_file=enable
+autocrop=enable
+autoscale=disable
max_width=480
max_height=0
-anamorphic=0
-keep_aspect=1
-detelecine=0
-decomb=0
+anamorphic=disable
+keep_aspect=enable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=0
-variable_frame_rate=0
+two_pass=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=960
video_target_size=700
video_quality=64
@@ -346,26 +346,26 @@ pref_audio_bitrate=160
pref_audio_rate=48
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-ipod_file=1
-autocrop=1
-autoscale=0
+ipod_file=enable
+autocrop=enable
+autoscale=disable
max_width=640
max_height=0
-anamorphic=0
-keep_aspect=1
-detelecine=0
-decomb=0
+anamorphic=disable
+keep_aspect=enable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=0
-variable_frame_rate=0
+two_pass=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1500
video_target_size=700
video_quality=64
@@ -380,26 +380,26 @@ pref_audio_bitrate=160
pref_audio_rate=48
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-ipod_file=1
-autocrop=1
-autoscale=0
+ipod_file=enable
+autocrop=enable
+autoscale=disable
max_width=320
max_height=0
-anamorphic=0
-keep_aspect=1
-detelecine=0
-decomb=0
+anamorphic=disable
+keep_aspect=enable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=0
-variable_frame_rate=0
+two_pass=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=700
video_target_size=700
video_quality=64
@@ -414,26 +414,26 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=1
-turbo=1
-variable_frame_rate=0
+two_pass=enable
+turbo=enable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1500
video_target_size=700
video_quality=64
@@ -448,25 +448,25 @@ pref_audio_bitrate=128
pref_audio_rate=48
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-autocrop=1
-autoscale=0
+autocrop=enable
+autoscale=disable
max_width=368
max_height=208
-anamorphic=0
-keep_aspect=1
-detelecine=0
-decomb=0
+anamorphic=disable
+keep_aspect=enable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=ffmpeg
-two_pass=0
-variable_frame_rate=0
+two_pass=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1024
video_target_size=700
video_quality=64
@@ -481,24 +481,24 @@ pref_audio_bitrate=160
pref_audio_rate=48
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=0
+chapter_markers=disable
container=mp4
-autoscale=1
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=0
-variable_frame_rate=0
+two_pass=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=2500
video_target_size=700
video_quality=64
@@ -513,26 +513,26 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mp4
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=1
-turbo=1
-variable_frame_rate=0
+two_pass=enable
+turbo=enable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=2000
video_target_size=700
video_quality=64
@@ -547,26 +547,26 @@ pref_audio_bitrate=160
pref_audio_rate=source
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=1
+chapter_markers=enable
container=mkv
-autocrop=1
-autoscale=1
+autocrop=enable
+autoscale=enable
max_width=0
max_height=0
-anamorphic=0
-keep_aspect=1
-detelecine=0
-decomb=0
+anamorphic=disable
+keep_aspect=enable
+detelecine=disable
+decomb=disable
deinterlace=slower
denoise=1
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=1
-turbo=1
-variable_frame_rate=0
+two_pass=enable
+turbo=enable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=1300
video_target_size=700
video_quality=64
@@ -581,24 +581,24 @@ pref_audio_bitrate=160
pref_audio_rate=48
pref_audio_mix=dpl2
pref_audio_drc=1
-chapter_markers=0
+chapter_markers=disable
container=mp4
-autoscale=1
+autoscale=enable
max_width=0
max_height=0
-anamorphic=1
-keep_aspect=0
-detelecine=0
-decomb=0
+anamorphic=enable
+keep_aspect=disable
+detelecine=disable
+decomb=disable
deinterlace=none
denoise=0
-grayscale=0
-deblock=0
+grayscale=disable
+deblock=disable
video_codec=x264
-two_pass=0
-variable_frame_rate=0
+two_pass=disable
+variable_frame_rate=disable
framerate=source
-vquality_type_bitrate=1
+vquality_type_bitrate=enable
video_bitrate=2000
video_target_size=700
video_quality=64
diff --git a/gtk/src/standard_presets.h b/gtk/src/standard_presets.h
index bfdfc059a..ecf3dc7f2 100644
--- a/gtk/src/standard_presets.h
+++ b/gtk/src/standard_presets.h
@@ -1,605 +1,1300 @@
-"\n"
-"[Animation]\n"
-"preset_description=HandBrake's settings for cartoons, anime, and CGI.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mkv\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=slower\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=1\n"
-"turbo=1\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1000\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=ref=5:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2\n"
-"\n"
-"[AppleTV]\n"
-"preset_description=HandBrake's settings for the AppleTV, including Dolby Digital 5.1 AC3 sound. Provides a good balance between quality and file size, and optimizes performance.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac,ac3\n"
-"pref_audio_bitrate=160,160\n"
-"pref_audio_rate=48,source\n"
-"pref_audio_mix=dpl2,none\n"
-"pref_audio_drc=1,1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"large_mp4=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=2500\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0\n"
-"\n"
-"[Bedlam]\n"
-"preset_description=HandBrake's settings maxed out for slowest encoding and highest quality. Use at your own risk. So slow it's not just insane...it's a trip to the looney bin.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=ac3\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=none\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mkv\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=1\n"
-"turbo=1\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1800\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"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\n"
-"\n"
-"[Blind]\n"
-"preset_description=HandBrake's preset for impatient people who don't care about picture quality.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=128\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"autocrop=1\n"
-"autoscale=0\n"
-"max_width=512\n"
-"max_height=0\n"
-"anamorphic=0\n"
-"keep_aspect=1\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=ffmpeg\n"
-"two_pass=0\n"
-"turbo=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=512\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=\n"
-"\n"
-"[Broke]\n"
-"preset_description=HandBrake's preset for people without a lot of money to waste on hard drives. Tries to maximize quality for burning to CDs, so you can party like it's 1999.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=128\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"autocrop=1\n"
-"autoscale=0\n"
-"max_width=640\n"
-"max_height=0\n"
-"anamorphic=0\n"
-"keep_aspect=1\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=1\n"
-"turbo=1\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_target=1\n"
-"video_bitrate=1600\n"
-"video_target_size=695\n"
-"video_quality=64\n"
-"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\n"
-"\n"
-"[Classic]\n"
-"preset_description=HandBrake's traditional, faster, lower-quality settings.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=0\n"
-"container=mp4\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=0\n"
-"keep_aspect=1\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=ffmpeg\n"
-"two_pass=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1000\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=\n"
-"\n"
-"[Constant Quality Rate]\n"
-"preset_description=HandBrake's preset for consistently excellent quality in one pass, with the downside of entirely unpredictable file sizes and bitrates.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=ac3\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=none\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mkv\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=0\n"
-"turbo=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_constant=1\n"
-"video_bitrate=2000\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"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\n"
-"\n"
-"[Deux Six Quatre]\n"
-"preset_description=HandBrake's preset for true high profile x264 quality. A good balance of quality and speed, based on community standards found in the wild. This preset will give you a much better sense of x264's capabilities than vanilla main profile.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=ac3\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=none\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mkv\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=1\n"
-"turbo=1\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1600\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"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\n"
-"\n"
-"[Film]\n"
-"preset_description=HandBrake's preset for feature films.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=ac3\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=none\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mkv\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=1\n"
-"turbo=1\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1800\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"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\n"
-"\n"
-"[iPhone / iPod Touch]\n"
-"preset_description=HandBrake's settings for the iPhone and iPod Touch.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=128\n"
-"pref_audio_rate=48\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"ipod_file=1\n"
-"autocrop=1\n"
-"autoscale=0\n"
-"max_width=480\n"
-"max_height=0\n"
-"anamorphic=0\n"
-"keep_aspect=1\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=960\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=level=30:cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1:trellis=1\n"
-"\n"
-"[iPod High-Rez]\n"
-"preset_description=HandBrake's high resolution settings for the iPod. Good video quality, great for viewing on a TV using your iPod\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=48\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"ipod_file=1\n"
-"autocrop=1\n"
-"autoscale=0\n"
-"max_width=640\n"
-"max_height=0\n"
-"anamorphic=0\n"
-"keep_aspect=1\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1500\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"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\n"
-"\n"
-"[iPod Low-Rez]\n"
-"preset_description=HandBrake's low resolution settings for the iPod. Optimized for great playback on the iPod screen, with smaller file size.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=48\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"ipod_file=1\n"
-"autocrop=1\n"
-"autoscale=0\n"
-"max_width=320\n"
-"max_height=0\n"
-"anamorphic=0\n"
-"keep_aspect=1\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=700\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"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\n"
-"\n"
-"[Normal]\n"
-"preset_description=HandBrake's normal, default settings.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=1\n"
-"turbo=1\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1500\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=ref=2:bframes=2:subme=5:me=umh\n"
-"\n"
-"[PSP]\n"
-"preset_description=HandBrake's settings for the Sony PlayStation Portable.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=128\n"
-"pref_audio_rate=48\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"autocrop=1\n"
-"autoscale=0\n"
-"max_width=368\n"
-"max_height=208\n"
-"anamorphic=0\n"
-"keep_aspect=1\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=ffmpeg\n"
-"two_pass=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1024\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=\n"
-"\n"
-"[PS3]\n"
-"preset_description=HandBrake's settings for the Sony PlayStation 3.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=48\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=0\n"
-"container=mp4\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=2500\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=level=41:subme=5:me=umh\n"
-"\n"
-"[QuickTime]\n"
-"preset_description=HandBrake's high quality settings for use with QuickTime. It can be slow, so use it when the Normal preset doesn't look good enough.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mp4\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=1\n"
-"turbo=1\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=2000\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=ref=3:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:me=umh:subme=5:analyse=all:trellis=1:no-fast-pskip\n"
-"\n"
-"[Television]\n"
-"preset_description=HandBrake's settings for video from television.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=source\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=1\n"
-"container=mkv\n"
-"autocrop=1\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=0\n"
-"keep_aspect=1\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=slower\n"
-"denoise=1\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=1\n"
-"turbo=1\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=1300\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"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\n"
-"\n"
-"[Xbox 360]\n"
-"preset_description=HandBrake's settings for the Microsoft Xbox 360.\n"
-"preset_type=0\n"
-"subtitle_lang=none\n"
-"pref_audio_codec=faac\n"
-"pref_audio_bitrate=160\n"
-"pref_audio_rate=48\n"
-"pref_audio_mix=dpl2\n"
-"pref_audio_drc=1\n"
-"chapter_markers=0\n"
-"container=mp4\n"
-"autoscale=1\n"
-"max_width=0\n"
-"max_height=0\n"
-"anamorphic=1\n"
-"keep_aspect=0\n"
-"detelecine=0\n"
-"decomb=0\n"
-"deinterlace=none\n"
-"denoise=0\n"
-"grayscale=0\n"
-"deblock=0\n"
-"video_codec=x264\n"
-"two_pass=0\n"
-"variable_frame_rate=0\n"
-"framerate=source\n"
-"vquality_type_bitrate=1\n"
-"video_bitrate=2000\n"
-"video_target_size=700\n"
-"video_quality=64\n"
-"x264_options=level=40:ref=2:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:no-fast-pskip:filter=-2,-1\n"
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+"<plist version=\"1.0\">\n"
+"<dict>\n"
+" <key>Animation</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mkv</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>slower</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's settings for cartoons, anime, and CGI.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <true />\n"
+" <key>two_pass</key>\n"
+" <true />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1000</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>ref=5:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2</string>\n"
+" </dict>\n"
+" <key>AppleTV</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>large_mp4</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>48</string>\n"
+" </dict>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>ac3</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>none</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's settings for the AppleTV, including Dolby Digital 5.1 AC3 sound. Provides a good balance between quality and file size, and optimizes performance.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>2500</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0</string>\n"
+" </dict>\n"
+" <key>Bedlam</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mkv</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>ac3</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>none</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's settings maxed out for slowest encoding and highest quality. Use at your own risk. So slow it's not just insane...it's a trip to the looney bin.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <true />\n"
+" <key>two_pass</key>\n"
+" <true />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1800</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>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</string>\n"
+" </dict>\n"
+" <key>Blind</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <false />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <false />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>512</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>128</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's preset for impatient people who don't care about picture quality.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <false />\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>512</integer>\n"
+" <key>video_codec</key>\n"
+" <string>ffmpeg</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string></string>\n"
+" </dict>\n"
+" <key>Broke</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <false />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <false />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>640</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>128</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's preset for people without a lot of money to waste on hard drives. Tries to maximize quality for burning to CDs, so you can party like it's 1999.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <true />\n"
+" <key>two_pass</key>\n"
+" <true />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1600</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>695</integer>\n"
+" <key>vquality_type_target</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>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</string>\n"
+" </dict>\n"
+" <key>Classic</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <false />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <false />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's traditional, faster, lower-quality settings.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1000</integer>\n"
+" <key>video_codec</key>\n"
+" <string>ffmpeg</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string></string>\n"
+" </dict>\n"
+" <key>Constant Quality Rate</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mkv</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>ac3</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>none</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's preset for consistently excellent quality in one pass, with the downside of entirely unpredictable file sizes and bitrates.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <false />\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>2000</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_constant</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>ref=3:mixed-refs:bframes=3:b-pyramid:b-rdo:bime:weightb:filter=-2,-1:subme=6:trellis=1:analyse=all:8x8dct:me=umh</string>\n"
+" </dict>\n"
+" <key>Deux Six Quatre</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mkv</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>ac3</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>none</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's preset for true high profile x264 quality. A good balance of quality and speed, based on community standards found in the wild. This preset will give you a much better sense of x264's capabilities than vanilla main profile.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <true />\n"
+" <key>two_pass</key>\n"
+" <true />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1600</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>ref=5:mixed-refs:bframes=3:bime:weightb:b-rdo:b-pyramid:me=umh:subme=7:trellis=1:analyse=all:8x8dct:no-fast-pskip</string>\n"
+" </dict>\n"
+" <key>Film</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mkv</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>ac3</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>none</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's preset for feature films.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <true />\n"
+" <key>two_pass</key>\n"
+" <true />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1800</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>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</string>\n"
+" </dict>\n"
+" <key>Normal</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's normal, default settings.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <true />\n"
+" <key>two_pass</key>\n"
+" <true />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1500</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>ref=2:bframes=2:subme=5:me=umh</string>\n"
+" </dict>\n"
+" <key>PS3</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <false />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>48</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's settings for the Sony PlayStation 3.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>2500</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>level=41:subme=5:me=umh</string>\n"
+" </dict>\n"
+" <key>PSP</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <false />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <false />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>208</integer>\n"
+" <key>max_width</key>\n"
+" <integer>368</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>128</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>48</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's settings for the Sony PlayStation Portable.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1024</integer>\n"
+" <key>video_codec</key>\n"
+" <string>ffmpeg</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string></string>\n"
+" </dict>\n"
+" <key>QuickTime</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's high quality settings for use with QuickTime. It can be slow, so use it when the Normal preset doesn't look good enough.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <true />\n"
+" <key>two_pass</key>\n"
+" <true />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>2000</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>ref=3:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:me=umh:subme=5:analyse=all:trellis=1:no-fast-pskip</string>\n"
+" </dict>\n"
+" <key>Television</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <false />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mkv</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>slower</string>\n"
+" <key>denoise</key>\n"
+" <integer>1</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>source</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's settings for video from television.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>turbo</key>\n"
+" <true />\n"
+" <key>two_pass</key>\n"
+" <true />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1300</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>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</string>\n"
+" </dict>\n"
+" <key>Xbox 360</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <true />\n"
+" <key>chapter_markers</key>\n"
+" <false />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>keep_aspect</key>\n"
+" <false />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>0</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>48</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's settings for the Microsoft Xbox 360.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>2000</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>level=40:ref=2:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:no-fast-pskip:filter=-2,-1</string>\n"
+" </dict>\n"
+" <key>iPhone / iPod Touch</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <false />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <false />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>ipod_file</key>\n"
+" <true />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>480</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>128</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>48</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's settings for the iPhone and iPod Touch.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>960</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>level=30:cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1:trellis=1</string>\n"
+" </dict>\n"
+" <key>iPod High-Rez</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <false />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <false />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>ipod_file</key>\n"
+" <true />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>640</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>48</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's high resolution settings for the iPod. Good video quality, great for viewing on a TV using your iPod</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>1500</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1</string>\n"
+" </dict>\n"
+" <key>iPod Low-Rez</key>\n"
+" <dict>\n"
+" <key>anamorphic</key>\n"
+" <false />\n"
+" <key>autocrop</key>\n"
+" <true />\n"
+" <key>autoscale</key>\n"
+" <false />\n"
+" <key>chapter_markers</key>\n"
+" <true />\n"
+" <key>container</key>\n"
+" <string>mp4</string>\n"
+" <key>deblock</key>\n"
+" <false />\n"
+" <key>decomb</key>\n"
+" <false />\n"
+" <key>deinterlace</key>\n"
+" <string>none</string>\n"
+" <key>denoise</key>\n"
+" <integer>0</integer>\n"
+" <key>detelecine</key>\n"
+" <false />\n"
+" <key>framerate</key>\n"
+" <string>source</string>\n"
+" <key>grayscale</key>\n"
+" <false />\n"
+" <key>ipod_file</key>\n"
+" <true />\n"
+" <key>keep_aspect</key>\n"
+" <true />\n"
+" <key>max_height</key>\n"
+" <integer>0</integer>\n"
+" <key>max_width</key>\n"
+" <integer>320</integer>\n"
+" <key>pref_audio_list</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>audio_bitrate</key>\n"
+" <string>160</string>\n"
+" <key>audio_codec</key>\n"
+" <string>faac</string>\n"
+" <key>audio_drc</key>\n"
+" <real>1</real>\n"
+" <key>audio_mix</key>\n"
+" <string>dpl2</string>\n"
+" <key>audio_rate</key>\n"
+" <string>48</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>preset_description</key>\n"
+" <string>HandBrake's low resolution settings for the iPod. Optimized for great playback on the iPod screen, with smaller file size.</string>\n"
+" <key>preset_type</key>\n"
+" <integer>0</integer>\n"
+" <key>subtitle_lang</key>\n"
+" <string>none</string>\n"
+" <key>two_pass</key>\n"
+" <false />\n"
+" <key>variable_frame_rate</key>\n"
+" <false />\n"
+" <key>video_bitrate</key>\n"
+" <integer>700</integer>\n"
+" <key>video_codec</key>\n"
+" <string>x264</string>\n"
+" <key>video_quality</key>\n"
+" <integer>64</integer>\n"
+" <key>video_target_size</key>\n"
+" <integer>700</integer>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <true />\n"
+" <key>x264_options</key>\n"
+" <string>level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1</string>\n"
+" </dict>\n"
+"</dict>\n"
+"</plist>\n"
diff --git a/gtk/src/standard_presets.xml b/gtk/src/standard_presets.xml
new file mode 100644
index 000000000..08c01282d
--- /dev/null
+++ b/gtk/src/standard_presets.xml
@@ -0,0 +1,1300 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Animation</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mkv</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>slower</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's settings for cartoons, anime, and CGI.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <true />
+ <key>two_pass</key>
+ <true />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1000</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>ref=5:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2</string>
+ </dict>
+ <key>AppleTV</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>large_mp4</key>
+ <true />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>48</string>
+ </dict>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>ac3</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>none</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's settings for the AppleTV, including Dolby Digital 5.1 AC3 sound. Provides a good balance between quality and file size, and optimizes performance.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>2500</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0</string>
+ </dict>
+ <key>Bedlam</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mkv</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>ac3</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>none</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's settings maxed out for slowest encoding and highest quality. Use at your own risk. So slow it's not just insane...it's a trip to the looney bin.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <true />
+ <key>two_pass</key>
+ <true />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1800</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>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</string>
+ </dict>
+ <key>Blind</key>
+ <dict>
+ <key>anamorphic</key>
+ <false />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <false />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <true />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>512</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>128</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's preset for impatient people who don't care about picture quality.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <false />
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>512</integer>
+ <key>video_codec</key>
+ <string>ffmpeg</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string></string>
+ </dict>
+ <key>Broke</key>
+ <dict>
+ <key>anamorphic</key>
+ <false />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <false />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <true />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>640</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>128</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's preset for people without a lot of money to waste on hard drives. Tries to maximize quality for burning to CDs, so you can party like it's 1999.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <true />
+ <key>two_pass</key>
+ <true />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1600</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>695</integer>
+ <key>vquality_type_target</key>
+ <true />
+ <key>x264_options</key>
+ <string>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</string>
+ </dict>
+ <key>Classic</key>
+ <dict>
+ <key>anamorphic</key>
+ <false />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <false />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <true />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's traditional, faster, lower-quality settings.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1000</integer>
+ <key>video_codec</key>
+ <string>ffmpeg</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string></string>
+ </dict>
+ <key>Constant Quality Rate</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mkv</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>ac3</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>none</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's preset for consistently excellent quality in one pass, with the downside of entirely unpredictable file sizes and bitrates.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <false />
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>2000</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_constant</key>
+ <true />
+ <key>x264_options</key>
+ <string>ref=3:mixed-refs:bframes=3:b-pyramid:b-rdo:bime:weightb:filter=-2,-1:subme=6:trellis=1:analyse=all:8x8dct:me=umh</string>
+ </dict>
+ <key>Deux Six Quatre</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mkv</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>ac3</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>none</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's preset for true high profile x264 quality. A good balance of quality and speed, based on community standards found in the wild. This preset will give you a much better sense of x264's capabilities than vanilla main profile.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <true />
+ <key>two_pass</key>
+ <true />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1600</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>ref=5:mixed-refs:bframes=3:bime:weightb:b-rdo:b-pyramid:me=umh:subme=7:trellis=1:analyse=all:8x8dct:no-fast-pskip</string>
+ </dict>
+ <key>Film</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mkv</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>ac3</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>none</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's preset for feature films.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <true />
+ <key>two_pass</key>
+ <true />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1800</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>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</string>
+ </dict>
+ <key>Normal</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's normal, default settings.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <true />
+ <key>two_pass</key>
+ <true />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1500</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>ref=2:bframes=2:subme=5:me=umh</string>
+ </dict>
+ <key>PS3</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <false />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>48</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's settings for the Sony PlayStation 3.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>2500</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>level=41:subme=5:me=umh</string>
+ </dict>
+ <key>PSP</key>
+ <dict>
+ <key>anamorphic</key>
+ <false />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <false />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <true />
+ <key>max_height</key>
+ <integer>208</integer>
+ <key>max_width</key>
+ <integer>368</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>128</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>48</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's settings for the Sony PlayStation Portable.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1024</integer>
+ <key>video_codec</key>
+ <string>ffmpeg</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string></string>
+ </dict>
+ <key>QuickTime</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's high quality settings for use with QuickTime. It can be slow, so use it when the Normal preset doesn't look good enough.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <true />
+ <key>two_pass</key>
+ <true />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>2000</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>ref=3:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:me=umh:subme=5:analyse=all:trellis=1:no-fast-pskip</string>
+ </dict>
+ <key>Television</key>
+ <dict>
+ <key>anamorphic</key>
+ <false />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mkv</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>slower</string>
+ <key>denoise</key>
+ <integer>1</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <true />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>source</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's settings for video from television.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>turbo</key>
+ <true />
+ <key>two_pass</key>
+ <true />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1300</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>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</string>
+ </dict>
+ <key>Xbox 360</key>
+ <dict>
+ <key>anamorphic</key>
+ <true />
+ <key>autoscale</key>
+ <true />
+ <key>chapter_markers</key>
+ <false />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>keep_aspect</key>
+ <false />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>0</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>48</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's settings for the Microsoft Xbox 360.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>2000</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>level=40:ref=2:mixed-refs:bframes=3:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=5:analyse=all:no-fast-pskip:filter=-2,-1</string>
+ </dict>
+ <key>iPhone / iPod Touch</key>
+ <dict>
+ <key>anamorphic</key>
+ <false />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <false />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>ipod_file</key>
+ <true />
+ <key>keep_aspect</key>
+ <true />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>480</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>128</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>48</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's settings for the iPhone and iPod Touch.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>960</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>level=30:cabac=0:ref=1:analyse=all:me=umh:subme=6:no-fast-pskip=1:trellis=1</string>
+ </dict>
+ <key>iPod High-Rez</key>
+ <dict>
+ <key>anamorphic</key>
+ <false />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <false />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>ipod_file</key>
+ <true />
+ <key>keep_aspect</key>
+ <true />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>640</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>48</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's high resolution settings for the iPod. Good video quality, great for viewing on a TV using your iPod</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>1500</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1</string>
+ </dict>
+ <key>iPod Low-Rez</key>
+ <dict>
+ <key>anamorphic</key>
+ <false />
+ <key>autocrop</key>
+ <true />
+ <key>autoscale</key>
+ <false />
+ <key>chapter_markers</key>
+ <true />
+ <key>container</key>
+ <string>mp4</string>
+ <key>deblock</key>
+ <false />
+ <key>decomb</key>
+ <false />
+ <key>deinterlace</key>
+ <string>none</string>
+ <key>denoise</key>
+ <integer>0</integer>
+ <key>detelecine</key>
+ <false />
+ <key>framerate</key>
+ <string>source</string>
+ <key>grayscale</key>
+ <false />
+ <key>ipod_file</key>
+ <true />
+ <key>keep_aspect</key>
+ <true />
+ <key>max_height</key>
+ <integer>0</integer>
+ <key>max_width</key>
+ <integer>320</integer>
+ <key>pref_audio_list</key>
+ <array>
+ <dict>
+ <key>audio_bitrate</key>
+ <string>160</string>
+ <key>audio_codec</key>
+ <string>faac</string>
+ <key>audio_drc</key>
+ <real>1</real>
+ <key>audio_mix</key>
+ <string>dpl2</string>
+ <key>audio_rate</key>
+ <string>48</string>
+ </dict>
+ </array>
+ <key>preset_description</key>
+ <string>HandBrake's low resolution settings for the iPod. Optimized for great playback on the iPod screen, with smaller file size.</string>
+ <key>preset_type</key>
+ <integer>0</integer>
+ <key>subtitle_lang</key>
+ <string>none</string>
+ <key>two_pass</key>
+ <false />
+ <key>variable_frame_rate</key>
+ <false />
+ <key>video_bitrate</key>
+ <integer>700</integer>
+ <key>video_codec</key>
+ <string>x264</string>
+ <key>video_quality</key>
+ <integer>64</integer>
+ <key>video_target_size</key>
+ <integer>700</integer>
+ <key>vquality_type_bitrate</key>
+ <true />
+ <key>x264_options</key>
+ <string>level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1</string>
+ </dict>
+</dict>
+</plist>
diff --git a/gtk/src/values.c b/gtk/src/values.c
new file mode 100644
index 000000000..8ef3bf365
--- /dev/null
+++ b/gtk/src/values.c
@@ -0,0 +1,678 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * presets.c
+ * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
+ *
+ * presets.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 <glib.h>
+#include <glib-object.h>
+#include <string.h>
+#include "values.h"
+
+static void dict_delete_key(gpointer data);
+static void dict_delete_value(gpointer data);
+
+GValue*
+ghb_value_new(GType gtype)
+{
+ GValue *gval = g_malloc0(sizeof(GValue));
+ g_value_init(gval, gtype);
+ return gval;
+}
+
+void
+ghb_value_free(GValue *gval)
+{
+ if (gval == NULL) return;
+ g_value_unset(gval);
+ g_free(gval);
+}
+
+GValue*
+ghb_value_dup(const GValue *val)
+{
+ if (val == NULL) return NULL;
+ GValue *copy = ghb_value_new(G_VALUE_TYPE(val));
+ g_value_copy(val, copy);
+ return copy;
+}
+
+gint
+ghb_value_int(const GValue *val)
+{
+ if (val == NULL) return 0;
+ const GValue *gval;
+ GValue xform = {0,};
+ if (G_VALUE_TYPE(val) != G_TYPE_INT64)
+ {
+ g_value_init(&xform, G_TYPE_INT64);
+ if (!g_value_transform(val, &xform))
+ return 0;
+ gval = &xform;
+ }
+ else
+ {
+ gval = val;
+ }
+ return (gint)g_value_get_int64(gval);
+}
+
+gint64
+ghb_value_int64(const GValue *val)
+{
+ if (val == NULL) return 0;
+ const GValue *gval;
+ GValue xform = {0,};
+ if (G_VALUE_TYPE(val) != G_TYPE_INT64)
+ {
+ g_value_init(&xform, G_TYPE_INT64);
+ if (!g_value_transform(val, &xform))
+ return 0;
+ gval = &xform;
+ }
+ else
+ {
+ gval = val;
+ }
+ return g_value_get_int64(gval);
+}
+
+gdouble
+ghb_value_double(const GValue *val)
+{
+ if (val == NULL) return 0;
+ const GValue *gval;
+ GValue xform = {0,};
+ if (G_VALUE_TYPE(val) != G_TYPE_DOUBLE)
+ {
+ g_value_init(&xform, G_TYPE_DOUBLE);
+ if (!g_value_transform(val, &xform))
+ return 0;
+ gval = &xform;
+ }
+ else
+ {
+ gval = val;
+ }
+ return g_value_get_double(gval);
+}
+
+gchar*
+ghb_value_string(const GValue *val)
+{
+ if (val == NULL) return 0;
+ const GValue *gval;
+ GValue xform = {0,};
+ if (G_VALUE_TYPE(val) != G_TYPE_STRING)
+ {
+ g_value_init(&xform, G_TYPE_STRING);
+ if (!g_value_transform(val, &xform))
+ return NULL;
+ gval = &xform;
+ }
+ else
+ {
+ gval = val;
+ }
+ return g_strdup(g_value_get_string(gval));
+}
+
+gboolean
+ghb_value_boolean(const GValue *val)
+{
+ if (val == NULL) return FALSE;
+ const GValue *gval;
+ GValue xform = {0,};
+ if (G_VALUE_TYPE(val) != G_TYPE_BOOLEAN)
+ {
+ g_value_init(&xform, G_TYPE_BOOLEAN);
+ if (!g_value_transform(val, &xform))
+ return FALSE;
+ gval = &xform;
+ }
+ else
+ {
+ gval = val;
+ }
+ return g_value_get_boolean(gval);
+}
+
+gint
+ghb_value_cmp(const GValue *vala, const GValue *valb)
+{
+ GType typa;
+ GType typb;
+
+ typa = G_VALUE_TYPE(vala);
+ typb = G_VALUE_TYPE(valb);
+ if (typa == ghb_combodata_get_type()) typa = G_TYPE_STRING;
+ if (typb == ghb_combodata_get_type()) typb = G_TYPE_STRING;
+ if (typa != typb)
+ {
+ return 1;
+ }
+
+ if (typa == G_TYPE_STRING)
+ {
+ char *stra, *strb;
+ gint res;
+ stra = ghb_value_string(vala);
+ strb = ghb_value_string(valb);
+ if (stra == NULL && strb == NULL)
+ return 0;
+ if (stra == NULL)
+ {
+ g_free(strb);
+ return -1;
+ }
+ if (strb == NULL)
+ {
+ g_free(stra);
+ return 1;
+ }
+ res = strcmp(stra, strb);
+ g_free(stra);
+ g_free(strb);
+ return res;
+ }
+ else if (typa == G_TYPE_INT64 || typa == G_TYPE_INT ||
+ typa == G_TYPE_BOOLEAN)
+ {
+ return ghb_value_int64(vala) - ghb_value_int64(valb);
+ }
+ else if (typa == G_TYPE_DOUBLE || typa == G_TYPE_FLOAT)
+ {
+ return ghb_value_double(vala) - ghb_value_double(valb);
+ }
+ else if (typa == ghb_array_get_type())
+ {
+ // Cheating here. Just assume they are different.
+ // Maybe later I'll recurse through these
+ return 1;
+ }
+ else if (typa == ghb_dict_get_type())
+ {
+ // Cheating here. Just assume they are different.
+ // Maybe later I'll recurse through these
+ return 1;
+ }
+ else
+ {
+ g_warning("ghb_value_cmp: unrecognized type");
+ return 1;
+ }
+ return 0;
+}
+
+GValue*
+ghb_string_value(const gchar *str)
+{
+ static GValue gval = {0,};
+ if (!G_IS_VALUE(&gval))
+ g_value_init(&gval, G_TYPE_STRING);
+ g_value_set_string(&gval, str);
+ return &gval;
+}
+
+GValue*
+ghb_int64_value(gint64 ival)
+{
+ static GValue gval = {0,};
+ if (!G_IS_VALUE(&gval))
+ g_value_init(&gval, G_TYPE_INT64);
+ g_value_set_int64(&gval, ival);
+ return &gval;
+}
+
+GValue*
+ghb_int_value(gint ival)
+{
+ static GValue gval = {0,};
+ if (!G_IS_VALUE(&gval))
+ g_value_init(&gval, G_TYPE_INT64);
+ g_value_set_int64(&gval, (gint64)ival);
+ return &gval;
+}
+
+GValue*
+ghb_double_value(gdouble dval)
+{
+ static GValue gval = {0,};
+ if (!G_IS_VALUE(&gval))
+ g_value_init(&gval, G_TYPE_DOUBLE);
+ g_value_set_double(&gval, dval);
+ return &gval;
+}
+
+GValue*
+ghb_boolean_value(gboolean bval)
+{
+ static GValue gval = {0,};
+ if (!G_IS_VALUE(&gval))
+ g_value_init(&gval, G_TYPE_BOOLEAN);
+ g_value_set_boolean(&gval, bval);
+ return &gval;
+}
+
+GValue*
+ghb_string_value_new(const gchar *str)
+{
+ if (str == NULL) str = "";
+ GValue *gval = ghb_value_new(G_TYPE_STRING);
+ g_value_set_string(gval, str);
+ return gval;
+}
+
+GValue*
+ghb_int64_value_new(gint64 ival)
+{
+ GValue *gval = ghb_value_new(G_TYPE_INT64);
+ g_value_set_int64(gval, ival);
+ return gval;
+}
+
+GValue*
+ghb_int_value_new(gint ival)
+{
+ GValue *gval = ghb_value_new(G_TYPE_INT64);
+ g_value_set_int64(gval, ival);
+ return gval;
+}
+
+GValue*
+ghb_double_value_new(gdouble dval)
+{
+ GValue *gval = ghb_value_new(G_TYPE_DOUBLE);
+ g_value_set_double(gval, dval);
+ return gval;
+}
+
+GValue*
+ghb_boolean_value_new(gboolean bval)
+{
+ GValue *gval = ghb_value_new(G_TYPE_BOOLEAN);
+ g_value_set_boolean(gval, bval);
+ return gval;
+}
+
+GValue*
+ghb_combo_value_new(
+ gint index,
+ const gchar *option,
+ const gchar *shortOpt,
+ const gchar *svalue,
+ gint ivalue)
+{
+ GValue *gval = ghb_value_new(ghb_combodata_get_type());
+ ghb_value_set_combodata(gval, index, option, shortOpt, svalue, ivalue);
+ return gval;
+}
+
+GValue*
+ghb_dict_value_new()
+{
+ GHashTable *dict;
+ GValue *gval = ghb_value_new(ghb_dict_get_type());
+ dict = g_hash_table_new_full(g_str_hash, g_str_equal,
+ dict_delete_key, dict_delete_value);
+ g_value_take_boxed(gval, dict);
+ return gval;
+}
+
+GValue*
+ghb_array_value_new(guint size)
+{
+ GValue *gval = ghb_value_new(ghb_array_get_type());
+ GArray *array;
+
+ array = g_array_sized_new(FALSE, FALSE, sizeof(GValue*), size);
+ g_value_take_boxed(gval, array);
+ return gval;
+}
+
+void
+ghb_array_value_reset(GValue *gval, guint size)
+{
+ GArray *array;
+ g_value_reset(gval);
+ array = g_array_sized_new(FALSE, FALSE, sizeof(GValue*), size);
+ g_value_take_boxed(gval, array);
+}
+
+GValue*
+ghb_date_value_new(GDate *date)
+{
+ GValue *gval = ghb_value_new(g_date_get_type());
+ g_value_set_boxed(gval, date);
+ return gval;
+}
+
+GValue*
+ghb_rawdata_value_new(ghb_rawdata_t *data)
+{
+ GValue *gval = ghb_value_new(ghb_rawdata_get_type());
+ g_value_take_boxed(gval, data);
+ return gval;
+}
+
+static gpointer
+combodata_copy(gpointer boxed)
+{
+ const ghb_combodata_t *combodata = (const ghb_combodata_t*)boxed;
+ ghb_combodata_t *copy = g_malloc0(sizeof(ghb_combodata_t));
+ if (combodata->option)
+ copy->option = g_strdup(combodata->option);
+ if (combodata->shortOpt)
+ copy->shortOpt = g_strdup(combodata->shortOpt);
+ if (combodata->svalue)
+ copy->svalue = g_strdup(combodata->svalue);
+
+ copy->index = combodata->index;
+ copy->ivalue = combodata->ivalue;
+ return copy;
+}
+
+static void
+combodata_free(gpointer boxed)
+{
+ ghb_combodata_t *combodata = (ghb_combodata_t*)boxed;
+ if (combodata->option)
+ g_free(combodata->option);
+ if (combodata->shortOpt)
+ g_free(combodata->shortOpt);
+ if (combodata->svalue)
+ g_free(combodata->svalue);
+ g_free(combodata);
+}
+
+
+static void
+xform_combodata_to_string(const GValue *combo, GValue *sval)
+{
+ const ghb_combodata_t *combodata = g_value_get_boxed(combo);
+ g_value_set_string(sval, combodata->shortOpt);
+}
+
+static void
+xform_combodata_to_int64(const GValue *combo, GValue *ival)
+{
+ const ghb_combodata_t *combodata = g_value_get_boxed(combo);
+ g_value_set_int64(ival, combodata->ivalue);
+}
+
+static void
+xform_combodata_to_double(const GValue *combo, GValue *dval)
+{
+ const ghb_combodata_t *combodata = g_value_get_boxed(combo);
+ g_value_set_double(dval, (gdouble)combodata->ivalue);
+}
+
+GType
+ghb_combodata_get_type(void)
+{
+ static GType type_id = 0;
+ if (!type_id)
+ {
+ type_id = g_boxed_type_register_static(
+ g_intern_static_string("GHBCombo"),
+ (GBoxedCopyFunc) combodata_copy,
+ (GBoxedFreeFunc) combodata_free);
+ g_value_register_transform_func(type_id, G_TYPE_STRING,
+ xform_combodata_to_string);
+ g_value_register_transform_func(type_id, G_TYPE_INT64,
+ xform_combodata_to_int64);
+ g_value_register_transform_func(type_id, G_TYPE_DOUBLE,
+ xform_combodata_to_double);
+ }
+ return type_id;
+}
+
+void
+ghb_value_set_combodata(
+ GValue *gval,
+ gint index,
+ const gchar *option,
+ const gchar *shortOpt,
+ const gchar *svalue,
+ gint ivalue)
+{
+ ghb_combodata_t combodata;
+ combodata.index = index;
+ combodata.option = g_strdup(option);
+ combodata.shortOpt = g_strdup(shortOpt);
+ combodata.svalue = g_strdup(svalue);
+ combodata.ivalue = ivalue;
+ g_value_set_boxed(gval, &combodata);
+}
+
+static gpointer
+rawdata_copy(gpointer boxed)
+{
+ const ghb_rawdata_t *data = (const ghb_rawdata_t*)boxed;
+ ghb_rawdata_t *copy = g_malloc(sizeof(ghb_rawdata_t));
+ copy->size = data->size;
+ if (data->data)
+ {
+ copy->data = g_malloc(data->size);
+ memcpy(copy->data, data->data, data->size);
+ }
+ else
+ {
+ copy->data = NULL;
+ copy->size = 0;
+ }
+ return copy;
+}
+
+static void
+rawdata_free(gpointer boxed)
+{
+ ghb_rawdata_t *data = (ghb_rawdata_t*)boxed;
+ if (data->data) g_free(data->data);
+ g_free(data);
+}
+
+
+GType
+ghb_rawdata_get_type(void)
+{
+ static GType type_id = 0;
+ if (!type_id)
+ type_id = g_boxed_type_register_static(g_intern_static_string("GHBData"),
+ (GBoxedCopyFunc) rawdata_copy,
+ (GBoxedFreeFunc) rawdata_free);
+ return type_id;
+}
+
+static void
+dict_delete_key(gpointer data)
+{
+ if (data == NULL)
+ {
+ g_warning("dict frees null key");
+ return;
+ }
+ g_free(data);
+}
+
+static void
+dict_delete_value(gpointer data)
+{
+ GValue *gval = (GValue*)data;
+ if (gval == NULL)
+ {
+ g_warning("dict frees null value");
+ return;
+ }
+ ghb_value_free(gval);
+}
+
+static gpointer
+dict_copy(gpointer boxed)
+{
+ GHashTable *dict = (GHashTable*)boxed;
+ GHashTable *copy;
+ GHashTableIter iter;
+ gchar *key;
+ GValue *gval;
+
+ copy = g_hash_table_new_full(g_str_hash, g_str_equal,
+ dict_delete_key, dict_delete_value);
+
+ g_hash_table_iter_init(&iter, dict);
+ while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&gval))
+ {
+ g_hash_table_insert(copy, g_strdup(key), ghb_value_dup(gval));
+ }
+ return copy;
+}
+
+static void
+dict_free(gpointer boxed)
+{
+ GHashTable *dict = (GHashTable*)boxed;
+ g_hash_table_destroy(dict);
+}
+
+
+GType
+ghb_dict_get_type(void)
+{
+ static GType type_id = 0;
+ if (!type_id)
+ type_id = g_boxed_type_register_static(
+ g_intern_static_string("GHBDict"),
+ (GBoxedCopyFunc) dict_copy,
+ (GBoxedFreeFunc) dict_free);
+ return type_id;
+}
+
+void
+ghb_dict_insert(GValue *gval, gchar *key, GValue *val)
+{
+ GHashTable *dict = g_value_get_boxed(gval);
+ g_hash_table_insert(dict, key, val);
+}
+
+void
+ghb_dict_iter_init(GHashTableIter *iter, GValue *gval)
+{
+ GHashTable *dict = g_value_get_boxed(gval);
+ g_hash_table_iter_init(iter, dict);
+}
+
+GValue*
+ghb_dict_lookup(GValue *gval, const gchar *key)
+{
+ GHashTable *dict = g_value_get_boxed(gval);
+ return g_hash_table_lookup(dict, key);
+}
+
+gboolean
+ghb_dict_remove(GValue *gval, const gchar *key)
+{
+ GHashTable *dict = g_value_get_boxed(gval);
+ return g_hash_table_remove(dict, key);
+}
+
+static gpointer
+array_copy(gpointer boxed)
+{
+ const GArray *array = (const GArray*)boxed;
+ GArray *copy = g_array_new(FALSE, FALSE, sizeof(GValue*));
+
+ GValue *gval, *gval_copy;
+ gint ii;
+
+ for (ii = 0; ii < array->len; ii++)
+ {
+ gval = g_array_index(array, GValue*, ii);
+ if (gval)
+ {
+ gval_copy = ghb_value_dup(gval);
+ g_array_append_val(copy, gval_copy);
+ }
+ }
+ return copy;
+}
+
+static void
+array_free(gpointer boxed)
+{
+ GArray *array = (GArray*)boxed;
+ GValue *gval;
+ gint ii;
+
+ for (ii = 0; ii < array->len; ii++)
+ {
+ gval = g_array_index(array, GValue*, ii);
+ if (gval)
+ {
+ ghb_value_free(gval);
+ }
+ }
+ g_array_free(array, TRUE);
+}
+
+
+GType
+ghb_array_get_type(void)
+{
+ static GType type_id = 0;
+ if (!type_id)
+ type_id = g_boxed_type_register_static(
+ g_intern_static_string("GHBArray"),
+ (GBoxedCopyFunc) array_copy,
+ (GBoxedFreeFunc) array_free);
+ return type_id;
+}
+
+GValue*
+ghb_array_get_nth(const GValue *gval, gint ii)
+{
+ GArray *arr = g_value_get_boxed(gval);
+ return g_array_index(arr, GValue*, ii);
+}
+
+void
+ghb_array_append(GValue *gval, GValue *val)
+{
+ GArray *arr = g_value_get_boxed(gval);
+ // A little nastyness here. The array pointer
+ // can change when the array changes size. So
+ // I must re-box it in the GValue each time.
+ arr = g_array_append_val(arr, val);
+ memset(gval, 0, sizeof(GValue));
+ g_value_init(gval, ghb_array_get_type());
+ g_value_take_boxed(gval, arr);
+}
+
+void
+ghb_array_remove(GValue *gval, guint ii)
+{
+ GArray *arr = g_value_get_boxed(gval);
+ // A little nastyness here. The array pointer
+ // can change when the array changes size. So
+ // I must re-box it in the GValue each time.
+ arr = g_array_remove_index(arr, ii);
+ memset(gval, 0, sizeof(GValue));
+ g_value_init(gval, ghb_array_get_type());
+ g_value_take_boxed(gval, arr);
+}
+
+gint
+ghb_array_len(const GValue *gval)
+{
+ if (gval == NULL) return 0;
+ GArray *arr = g_value_get_boxed(gval);
+ return arr->len;
+}
+
diff --git a/gtk/src/values.h b/gtk/src/values.h
new file mode 100644
index 000000000..e5b42a711
--- /dev/null
+++ b/gtk/src/values.h
@@ -0,0 +1,95 @@
+/*
+ * This program is free software; you can 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.
+ *
+ * This program 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
+ */
+#if !defined(_GHB_VALUES_H_)
+#define _GHB_VALUES_H_
+
+#include <glib.h>
+#include <glib-object.h>
+
+typedef struct
+{
+ guchar *data;
+ gsize size;
+} ghb_rawdata_t;
+
+typedef struct
+{
+ gint index;
+ gchar *option;
+ gchar *shortOpt;
+ gchar *svalue;
+ gint ivalue;
+} ghb_combodata_t;
+
+GType ghb_combodata_get_type(void);
+void ghb_value_set_combodata(
+ GValue *gval,
+ gint index,
+ const gchar *option,
+ const gchar *shortOpt,
+ const gchar *svalue,
+ gint ivalue);
+
+GType ghb_rawdata_get_type(void);
+
+GType ghb_array_get_type(void);
+GType ghb_dict_get_type(void);
+GValue* ghb_array_get_nth(const GValue *array, gint ii);
+void ghb_array_append(GValue *gval, GValue *val);
+void ghb_array_remove(GValue *gval, guint ii);
+gint ghb_array_len(const GValue *gval);
+
+void ghb_value_free(GValue *gval);
+GValue* ghb_value_new(GType gtype);
+GValue* ghb_value_dup(const GValue *val);
+gint ghb_value_int(const GValue *val);
+gint64 ghb_value_int64(const GValue *val);
+gdouble ghb_value_double(const GValue *val);
+gchar* ghb_value_string(const GValue *val);
+gboolean ghb_value_boolean(const GValue *val);
+
+GValue* ghb_string_value(const gchar *str);
+GValue* ghb_int64_value(gint64 ival);
+GValue* ghb_int_value(gint ival);
+GValue* ghb_double_value(gdouble dval);
+GValue* ghb_boolean_value(gboolean bval);
+
+gint ghb_value_cmp(const GValue *vala, const GValue *valb);
+GValue* ghb_string_value_new(const gchar *str);
+GValue* ghb_int64_value_new(gint64 ival);
+GValue* ghb_int_value_new(gint ival);
+GValue* ghb_double_value_new(gdouble dval);
+GValue* ghb_boolean_value_new(gboolean bval);
+GValue* ghb_combo_value_new(
+ gint index,
+ const gchar *option,
+ const gchar *shortOpt,
+ const gchar *svalue,
+ gint ivalue);
+GValue* ghb_dict_value_new(void);
+GValue* ghb_array_value_new(guint size);
+void ghb_array_value_reset(GValue *gval, guint size);
+
+GValue* ghb_date_value_new(GDate *date);
+GValue* ghb_rawdata_value_new(ghb_rawdata_t *data);
+
+void ghb_dict_insert(GValue *gval, gchar *key, GValue *val);
+void ghb_dict_iter_init(GHashTableIter *iter, GValue *gval);
+GValue* ghb_dict_lookup(GValue *gval, const gchar *key);
+gboolean ghb_dict_remove(GValue *gval, const gchar *key);
+
+
+#endif // _GHB_VALUES_H_
diff --git a/gtk/src/widget_deps b/gtk/src/widget_deps
new file mode 100644
index 000000000..228acd329
--- /dev/null
+++ b/gtk/src/widget_deps
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>anamorphic</key>
+ <array>
+ <string>keep_aspect</string>
+ <string>scale_height</string>
+ </array>
+ <key>audio_codec</key>
+ <array>
+ <string>audio_bitrate</string>
+ <string>audio_rate</string>
+ <string>audio_mix</string>
+ <string>audio_drc</string>
+ </array>
+ <key>autocrop</key>
+ <array>
+ <string>crop_top</string>
+ <string>crop_bottom</string>
+ <string>crop_left</string>
+ <string>crop_right</string>
+ </array>
+ <key>autoscale</key>
+ <array>
+ <string>scale_width</string>
+ <string>scale_height</string>
+ </array>
+ <key>chapter_markers</key>
+ <array>
+ <string>chapters_list</string>
+ </array>
+ <key>container</key>
+ <array>
+ <string>large_mp4</string>
+ <string>http_optimize_mp4</string>
+ <string>ipod_file</string>
+ <string>variable_frame_rate</string>
+ </array>
+ <key>decomb</key>
+ <array>
+ <string>deinterlace</string>
+ <string>tweak_deinterlace</string>
+ </array>
+ <key>keep_aspect</key>
+ <array>
+ <string>scale_height</string>
+ </array>
+ <key>title</key>
+ <array>
+ <string>queue_add</string>
+ <string>queue_add_menu</string>
+ <string>preview_button</string>
+ <string>show_preview_menu</string>
+ <string>preview_frame</string>
+ <string>picture_label</string>
+ <string>picture_tab</string>
+ <string>chapters_label</string>
+ <string>chapters_tab</string>
+ <string>title</string>
+ <string>start_chapter</string>
+ <string>end_chapter</string>
+ </array>
+ <key>two_pass</key>
+ <array>
+ <string>turbo</string>
+ </array>
+ <key>variable_frame_rate</key>
+ <array>
+ <string>framerate</string>
+ <string>detelecine</string>
+ </array>
+ <key>video_codec</key>
+ <array>
+ <string>x264_tab</string>
+ <string>x264_tab_label</string>
+ <string>ipod_file</string>
+ </array>
+ <key>vquality_type_bitrate</key>
+ <array>
+ <string>video_bitrate</string>
+ </array>
+ <key>vquality_type_constant</key>
+ <array>
+ <string>video_quality</string>
+ <string>constant_rate_factor</string>
+ <string>two_pass</string>
+ <string>turbo</string>
+ </array>
+ <key>vquality_type_target</key>
+ <array>
+ <string>video_target_size</string>
+ </array>
+ <key>x264_analyse</key>
+ <array>
+ <string>x264_direct</string>
+ </array>
+ <key>x264_bframes</key>
+ <array>
+ <string>x264_weighted_bframes</string>
+ <string>x264_brdo</string>
+ <string>x264_bime</string>
+ <string>x264_bpyramid</string>
+ <string>x264_direct</string>
+ </array>
+ <key>x264_cabac</key>
+ <array>
+ <string>x264_trellis</string>
+ </array>
+ <key>x264_me</key>
+ <array>
+ <string>x264_merange</string>
+ </array>
+ <key>x264_refs</key>
+ <array>
+ <string>x264_mixed_refs</string>
+ </array>
+ <key>x264_subme</key>
+ <array>
+ <string>x264_brdo</string>
+ </array>
+</dict>
+</plist>
diff --git a/gtk/src/widget_deps.h b/gtk/src/widget_deps.h
new file mode 100644
index 000000000..9a5064ceb
--- /dev/null
+++ b/gtk/src/widget_deps.h
@@ -0,0 +1,123 @@
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+"<plist version=\"1.0\">\n"
+"<dict>\n"
+" <key>anamorphic</key>\n"
+" <array>\n"
+" <string>keep_aspect</string>\n"
+" <string>scale_height</string>\n"
+" </array>\n"
+" <key>audio_codec</key>\n"
+" <array>\n"
+" <string>audio_bitrate</string>\n"
+" <string>audio_rate</string>\n"
+" <string>audio_mix</string>\n"
+" <string>audio_drc</string>\n"
+" </array>\n"
+" <key>autocrop</key>\n"
+" <array>\n"
+" <string>crop_top</string>\n"
+" <string>crop_bottom</string>\n"
+" <string>crop_left</string>\n"
+" <string>crop_right</string>\n"
+" </array>\n"
+" <key>autoscale</key>\n"
+" <array>\n"
+" <string>scale_width</string>\n"
+" <string>scale_height</string>\n"
+" </array>\n"
+" <key>chapter_markers</key>\n"
+" <array>\n"
+" <string>chapters_list</string>\n"
+" </array>\n"
+" <key>container</key>\n"
+" <array>\n"
+" <string>large_mp4</string>\n"
+" <string>http_optimize_mp4</string>\n"
+" <string>ipod_file</string>\n"
+" <string>variable_frame_rate</string>\n"
+" </array>\n"
+" <key>decomb</key>\n"
+" <array>\n"
+" <string>deinterlace</string>\n"
+" <string>tweak_deinterlace</string>\n"
+" </array>\n"
+" <key>keep_aspect</key>\n"
+" <array>\n"
+" <string>scale_height</string>\n"
+" </array>\n"
+" <key>title</key>\n"
+" <array>\n"
+" <string>queue_add</string>\n"
+" <string>queue_add_menu</string>\n"
+" <string>preview_button</string>\n"
+" <string>show_preview_menu</string>\n"
+" <string>preview_frame</string>\n"
+" <string>picture_label</string>\n"
+" <string>picture_tab</string>\n"
+" <string>chapters_label</string>\n"
+" <string>chapters_tab</string>\n"
+" <string>title</string>\n"
+" <string>start_chapter</string>\n"
+" <string>end_chapter</string>\n"
+" </array>\n"
+" <key>two_pass</key>\n"
+" <array>\n"
+" <string>turbo</string>\n"
+" </array>\n"
+" <key>variable_frame_rate</key>\n"
+" <array>\n"
+" <string>framerate</string>\n"
+" <string>detelecine</string>\n"
+" </array>\n"
+" <key>video_codec</key>\n"
+" <array>\n"
+" <string>x264_tab</string>\n"
+" <string>x264_tab_label</string>\n"
+" <string>ipod_file</string>\n"
+" </array>\n"
+" <key>vquality_type_bitrate</key>\n"
+" <array>\n"
+" <string>video_bitrate</string>\n"
+" </array>\n"
+" <key>vquality_type_constant</key>\n"
+" <array>\n"
+" <string>video_quality</string>\n"
+" <string>constant_rate_factor</string>\n"
+" <string>two_pass</string>\n"
+" <string>turbo</string>\n"
+" </array>\n"
+" <key>vquality_type_target</key>\n"
+" <array>\n"
+" <string>video_target_size</string>\n"
+" </array>\n"
+" <key>x264_analyse</key>\n"
+" <array>\n"
+" <string>x264_direct</string>\n"
+" </array>\n"
+" <key>x264_bframes</key>\n"
+" <array>\n"
+" <string>x264_weighted_bframes</string>\n"
+" <string>x264_brdo</string>\n"
+" <string>x264_bime</string>\n"
+" <string>x264_bpyramid</string>\n"
+" <string>x264_direct</string>\n"
+" </array>\n"
+" <key>x264_cabac</key>\n"
+" <array>\n"
+" <string>x264_trellis</string>\n"
+" </array>\n"
+" <key>x264_me</key>\n"
+" <array>\n"
+" <string>x264_merange</string>\n"
+" </array>\n"
+" <key>x264_refs</key>\n"
+" <array>\n"
+" <string>x264_mixed_refs</string>\n"
+" </array>\n"
+" <key>x264_subme</key>\n"
+" <array>\n"
+" <string>x264_brdo</string>\n"
+" </array>\n"
+"</dict>\n"
+"</plist>\n"
diff --git a/gtk/src/widget_reverse_deps b/gtk/src/widget_reverse_deps
new file mode 100644
index 000000000..6b876e952
--- /dev/null
+++ b/gtk/src/widget_reverse_deps
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>audio_bitrate</key>
+ <array>
+ <array>
+ <string>audio_codec</string>
+ <string>ac3</string>
+ <true />
+ </array>
+ </array>
+ <key>audio_drc</key>
+ <array>
+ <array>
+ <string>audio_codec</string>
+ <string>ac3</string>
+ <true />
+ </array>
+ </array>
+ <key>audio_mix</key>
+ <array>
+ <array>
+ <string>audio_codec</string>
+ <string>ac3</string>
+ <true />
+ </array>
+ </array>
+ <key>audio_rate</key>
+ <array>
+ <array>
+ <string>audio_codec</string>
+ <string>ac3</string>
+ <true />
+ </array>
+ </array>
+ <key>chapters_label</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>chapters_list</key>
+ <array>
+ <array>
+ <string>chapter_markers</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
+ <key>chapters_tab</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>constant_rate_factor</key>
+ <array>
+ <array>
+ <string>vquality_type_constant</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
+ <key>crop_bottom</key>
+ <array>
+ <array>
+ <string>autocrop</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ </array>
+ <key>crop_left</key>
+ <array>
+ <array>
+ <string>autocrop</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ </array>
+ <key>crop_right</key>
+ <array>
+ <array>
+ <string>autocrop</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ </array>
+ <key>crop_top</key>
+ <array>
+ <array>
+ <string>autocrop</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ </array>
+ <key>deinterlace</key>
+ <array>
+ <array>
+ <string>decomb</string>
+ <string>TRUE</string>
+ <true />
+ </array>
+ </array>
+ <key>detelecine</key>
+ <array>
+ <array>
+ <string>variable_frame_rate</string>
+ <string>TRUE</string>
+ <true />
+ </array>
+ </array>
+ <key>end_chapter</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>framerate</key>
+ <array>
+ <array>
+ <string>variable_frame_rate</string>
+ <string>TRUE</string>
+ <true />
+ </array>
+ </array>
+ <key>http_optimize_mp4</key>
+ <array>
+ <array>
+ <string>container</string>
+ <string>mp4|m4v</string>
+ <false />
+ </array>
+ </array>
+ <key>ipod_file</key>
+ <array>
+ <array>
+ <string>container</string>
+ <string>mp4|m4v</string>
+ <false />
+ </array>
+ <array>
+ <string>video_codec</string>
+ <string>x264</string>
+ <false />
+ </array>
+ </array>
+ <key>keep_aspect</key>
+ <array>
+ <array>
+ <string>anamorphic</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ </array>
+ <key>large_mp4</key>
+ <array>
+ <array>
+ <string>container</string>
+ <string>mp4|m4v</string>
+ <false />
+ </array>
+ </array>
+ <key>picture_label</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>picture_tab</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>preview_button</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>preview_frame</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>queue_add</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>queue_add_menu</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>scale_height</key>
+ <array>
+ <array>
+ <string>autoscale</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ <array>
+ <string>anamorphic</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ <array>
+ <string>keep_aspect</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ </array>
+ <key>scale_width</key>
+ <array>
+ <array>
+ <string>autoscale</string>
+ <string>FALSE</string>
+ <false />
+ </array>
+ </array>
+ <key>show_preview_menu</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>start_chapter</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>title</key>
+ <array>
+ <array>
+ <string>title</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>turbo</key>
+ <array>
+ <array>
+ <string>vquality_type_constant</string>
+ <string>TRUE</string>
+ <true />
+ </array>
+ <array>
+ <string>two_pass</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
+ <key>tweak_deinterlace</key>
+ <array>
+ <array>
+ <string>decomb</string>
+ <string>TRUE</string>
+ <true />
+ </array>
+ </array>
+ <key>two_pass</key>
+ <array>
+ <array>
+ <string>vquality_type_constant</string>
+ <string>TRUE</string>
+ <true />
+ </array>
+ </array>
+ <key>variable_frame_rate</key>
+ <array>
+ <array>
+ <string>container</string>
+ <string>avi</string>
+ <true />
+ </array>
+ </array>
+ <key>video_bitrate</key>
+ <array>
+ <array>
+ <string>vquality_type_bitrate</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
+ <key>video_quality</key>
+ <array>
+ <array>
+ <string>vquality_type_constant</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
+ <key>video_target_size</key>
+ <array>
+ <array>
+ <string>vquality_type_target</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
+ <key>x264_bime</key>
+ <array>
+ <array>
+ <string>x264_bframes</string>
+ <string>0</string>
+ <true />
+ </array>
+ </array>
+ <key>x264_bpyramid</key>
+ <array>
+ <array>
+ <string>x264_bframes</string>
+ <string>&lt;2</string>
+ <true />
+ </array>
+ </array>
+ <key>x264_brdo</key>
+ <array>
+ <array>
+ <string>x264_bframes</string>
+ <string>0</string>
+ <true />
+ </array>
+ <array>
+ <string>x264_subme</string>
+ <string>&lt;6</string>
+ <true />
+ </array>
+ </array>
+ <key>x264_direct</key>
+ <array>
+ <array>
+ <string>x264_bframes</string>
+ <string>0</string>
+ <true />
+ </array>
+ <array>
+ <string>x264_analyse</string>
+ <string>none</string>
+ <true />
+ </array>
+ </array>
+ <key>x264_merange</key>
+ <array>
+ <array>
+ <string>x264_me</string>
+ <string>umh|esa</string>
+ <false />
+ </array>
+ </array>
+ <key>x264_mixed_refs</key>
+ <array>
+ <array>
+ <string>x264_refs</string>
+ <string>&lt;2</string>
+ <true />
+ </array>
+ </array>
+ <key>x264_tab</key>
+ <array>
+ <array>
+ <string>video_codec</string>
+ <string>x264</string>
+ <false />
+ </array>
+ </array>
+ <key>x264_tab_label</key>
+ <array>
+ <array>
+ <string>video_codec</string>
+ <string>x264</string>
+ <false />
+ </array>
+ </array>
+ <key>x264_trellis</key>
+ <array>
+ <array>
+ <string>x264_cabac</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
+ <key>x264_weighted_bframes</key>
+ <array>
+ <array>
+ <string>x264_bframes</string>
+ <string>0</string>
+ <true />
+ </array>
+ </array>
+</dict>
+</plist>
diff --git a/gtk/src/widget_reverse_deps.h b/gtk/src/widget_reverse_deps.h
new file mode 100644
index 000000000..febfea408
--- /dev/null
+++ b/gtk/src/widget_reverse_deps.h
@@ -0,0 +1,420 @@
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+"<plist version=\"1.0\">\n"
+"<dict>\n"
+" <key>audio_bitrate</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>audio_codec</string>\n"
+" <string>ac3</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>audio_drc</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>audio_codec</string>\n"
+" <string>ac3</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>audio_mix</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>audio_codec</string>\n"
+" <string>ac3</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>audio_rate</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>audio_codec</string>\n"
+" <string>ac3</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>chapters_label</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>chapters_list</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>chapter_markers</string>\n"
+" <string>TRUE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>chapters_tab</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>constant_rate_factor</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>vquality_type_constant</string>\n"
+" <string>TRUE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>crop_bottom</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>autocrop</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>crop_left</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>autocrop</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>crop_right</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>autocrop</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>crop_top</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>autocrop</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>deinterlace</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>decomb</string>\n"
+" <string>TRUE</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>detelecine</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>variable_frame_rate</string>\n"
+" <string>TRUE</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>end_chapter</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>framerate</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>variable_frame_rate</string>\n"
+" <string>TRUE</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>http_optimize_mp4</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>container</string>\n"
+" <string>mp4|m4v</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>ipod_file</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>container</string>\n"
+" <string>mp4|m4v</string>\n"
+" <false />\n"
+" </array>\n"
+" <array>\n"
+" <string>video_codec</string>\n"
+" <string>x264</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>keep_aspect</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>anamorphic</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>large_mp4</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>container</string>\n"
+" <string>mp4|m4v</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>picture_label</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>picture_tab</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>preview_button</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>preview_frame</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>queue_add</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>queue_add_menu</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>scale_height</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>autoscale</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" <array>\n"
+" <string>anamorphic</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" <array>\n"
+" <string>keep_aspect</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>scale_width</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>autoscale</string>\n"
+" <string>FALSE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>show_preview_menu</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>start_chapter</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>title</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>title</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>turbo</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>vquality_type_constant</string>\n"
+" <string>TRUE</string>\n"
+" <true />\n"
+" </array>\n"
+" <array>\n"
+" <string>two_pass</string>\n"
+" <string>TRUE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>tweak_deinterlace</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>decomb</string>\n"
+" <string>TRUE</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>two_pass</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>vquality_type_constant</string>\n"
+" <string>TRUE</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>variable_frame_rate</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>container</string>\n"
+" <string>avi</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>video_bitrate</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>vquality_type_bitrate</string>\n"
+" <string>TRUE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>video_quality</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>vquality_type_constant</string>\n"
+" <string>TRUE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>video_target_size</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>vquality_type_target</string>\n"
+" <string>TRUE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_bime</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>x264_bframes</string>\n"
+" <string>0</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_bpyramid</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>x264_bframes</string>\n"
+" <string>&lt;2</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_brdo</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>x264_bframes</string>\n"
+" <string>0</string>\n"
+" <true />\n"
+" </array>\n"
+" <array>\n"
+" <string>x264_subme</string>\n"
+" <string>&lt;6</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_direct</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>x264_bframes</string>\n"
+" <string>0</string>\n"
+" <true />\n"
+" </array>\n"
+" <array>\n"
+" <string>x264_analyse</string>\n"
+" <string>none</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_merange</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>x264_me</string>\n"
+" <string>umh|esa</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_mixed_refs</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>x264_refs</string>\n"
+" <string>&lt;2</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_tab</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>video_codec</string>\n"
+" <string>x264</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_tab_label</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>video_codec</string>\n"
+" <string>x264</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_trellis</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>x264_cabac</string>\n"
+" <string>TRUE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
+" <key>x264_weighted_bframes</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>x264_bframes</string>\n"
+" <string>0</string>\n"
+" <true />\n"
+" </array>\n"
+" </array>\n"
+"</dict>\n"
+"</plist>\n"