diff options
author | jstebbins <[email protected]> | 2008-09-02 22:56:19 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2008-09-02 22:56:19 +0000 |
commit | 45cabbfe4ab8b95b5f25a236f8c93b64d3ccf8df (patch) | |
tree | 40326771d4a7f4721363e3b76ebfca5329595deb /gtk/src | |
parent | fd744170cb1da2675e1168402866f5c20f08a726 (diff) |
LinGui: Presets and preferences are now stored as plists
This will also make saving/restoring the queue much easier.
It's a scary big change. 1400 new lines of code. Due to efficiencies
of a better desing, 2400 lines of old code also gets refactored
down to 1600. Giving a final net +600 lines.
Along the way, I stumbled across a couple bugs and fixed them.
Chapter list entry would get wedged under certain circumstances.
Pausing encoding didn't display pause message in status bar.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1662 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'gtk/src')
-rw-r--r-- | gtk/src/Makefile.am | 33 | ||||
-rw-r--r-- | gtk/src/callbacks.c | 1526 | ||||
-rw-r--r-- | gtk/src/callbacks.h | 8 | ||||
-rw-r--r-- | gtk/src/hb-backend.c | 467 | ||||
-rw-r--r-- | gtk/src/hb-backend.h | 45 | ||||
-rw-r--r-- | gtk/src/ini_to_plist.c | 104 | ||||
-rw-r--r-- | gtk/src/internal_defaults.h | 287 | ||||
-rw-r--r-- | gtk/src/internal_defaults.xml | 197 | ||||
-rw-r--r-- | gtk/src/main.c | 50 | ||||
-rw-r--r-- | gtk/src/makedeps.c | 136 | ||||
-rw-r--r-- | gtk/src/plist.c | 587 | ||||
-rw-r--r-- | gtk/src/plist.h | 14 | ||||
-rw-r--r-- | gtk/src/preset_to_string.c | 35 | ||||
-rw-r--r-- | gtk/src/presets.c | 722 | ||||
-rw-r--r-- | gtk/src/presets.h | 37 | ||||
-rw-r--r-- | gtk/src/settings.c | 1758 | ||||
-rw-r--r-- | gtk/src/settings.h | 112 | ||||
-rwxr-xr-x | gtk/src/standard_presets | 454 | ||||
-rw-r--r-- | gtk/src/standard_presets.h | 1905 | ||||
-rw-r--r-- | gtk/src/standard_presets.xml | 1300 | ||||
-rw-r--r-- | gtk/src/values.c | 678 | ||||
-rw-r--r-- | gtk/src/values.h | 95 | ||||
-rw-r--r-- | gtk/src/widget_deps | 123 | ||||
-rw-r--r-- | gtk/src/widget_deps.h | 123 | ||||
-rw-r--r-- | gtk/src/widget_reverse_deps | 420 | ||||
-rw-r--r-- | gtk/src/widget_reverse_deps.h | 420 |
26 files changed, 8334 insertions, 3302 deletions
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><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><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><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><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><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><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" |