diff options
author | jstebbins <[email protected]> | 2015-05-14 17:11:48 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2015-05-14 17:11:48 +0000 |
commit | 9ae7e30dc8daace92d17ea36a4f0bdede00b9471 (patch) | |
tree | 9485255c993389a6740b833e7aa30c5b5b2622aa | |
parent | 90cafad3e4c610b8b009769f922fabc283979231 (diff) |
lingui: use libhb preset management from linux gui
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@7179 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | gtk/src/Makefile.am | 8 | ||||
-rw-r--r-- | gtk/src/callbacks.c | 54 | ||||
-rw-r--r-- | gtk/src/callbacks.h | 1 | ||||
-rw-r--r-- | gtk/src/data_res.gresource.xml | 1 | ||||
-rw-r--r-- | gtk/src/ghb-3.12.ui | 4 | ||||
-rw-r--r-- | gtk/src/ghb-3.14.ui | 4 | ||||
-rw-r--r-- | gtk/src/ghb.ui | 4 | ||||
-rw-r--r-- | gtk/src/internal_defaults.json | 117 | ||||
-rw-r--r-- | gtk/src/main.c | 19 | ||||
-rw-r--r-- | gtk/src/presets.c | 4045 | ||||
-rw-r--r-- | gtk/src/presets.h | 19 | ||||
-rw-r--r-- | gtk/src/queuehandler.c | 11 | ||||
-rw-r--r-- | gtk/src/resources.c | 7 | ||||
-rw-r--r-- | gtk/src/standard_presets.json | 867 | ||||
-rw-r--r-- | gtk/src/values.c | 29 | ||||
-rw-r--r-- | gtk/src/values.h | 2 | ||||
-rw-r--r-- | libhb/builtin_presets.h | 509 | ||||
-rw-r--r-- | libhb/hb.h | 1 | ||||
-rw-r--r-- | libhb/hb_dict.c | 14 | ||||
-rw-r--r-- | libhb/hb_dict.h | 5 | ||||
-rw-r--r-- | libhb/plist.c | 25 | ||||
-rw-r--r-- | libhb/plist.h | 9 | ||||
-rw-r--r-- | libhb/preset.c | 1294 | ||||
-rw-r--r-- | libhb/preset.h | 130 | ||||
-rw-r--r-- | libhb/preset_builtin.json | 497 | ||||
-rw-r--r-- | libhb/preset_template.json | 13 | ||||
-rw-r--r-- | libhb/work.c | 17 | ||||
-rwxr-xr-x | scripts/create_resources.py | 5 | ||||
-rw-r--r-- | test/test.c | 9 |
29 files changed, 2805 insertions, 4915 deletions
diff --git a/gtk/src/Makefile.am b/gtk/src/Makefile.am index dc9f48941..e72ba59af 100644 --- a/gtk/src/Makefile.am +++ b/gtk/src/Makefile.am @@ -100,12 +100,12 @@ icon_res.h : icon_res.gresource.xml $(icons_dep) icon_res.o: icon_res.c icon_res.h -data_res.c : data_res.gresource.xml $(srcdir)/internal_defaults.json $(srcdir)/standard_presets.json widget.deps widget_reverse.deps - cp $(srcdir)/internal_defaults.json $(srcdir)/standard_presets.json . +data_res.c : data_res.gresource.xml $(srcdir)/internal_defaults.json widget.deps widget_reverse.deps + cp $(srcdir)/internal_defaults.json . glib-compile-resources --generate --target=$@ --c-name ghb_data --manual-register $< -data_res.h : data_res.gresource.xml $(srcdir)/internal_defaults.json $(srcdir)/standard_presets.json widget.deps widget_reverse.deps - cp $(srcdir)/internal_defaults.json $(srcdir)/standard_presets.json . +data_res.h : data_res.gresource.xml $(srcdir)/internal_defaults.json widget.deps widget_reverse.deps + cp $(srcdir)/internal_defaults.json . glib-compile-resources --generate --target=$@ --c-name ghb_data --manual-register $< if GHB_GTK_3_14 diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c index 5fc3d7589..5b5db99af 100644 --- a/gtk/src/callbacks.c +++ b/gtk/src/callbacks.c @@ -818,14 +818,14 @@ update_source_label(signal_user_data_t *ud, const gchar *source) if (label != NULL) { gtk_label_set_text (GTK_LABEL(widget), label); - ghb_dict_set_string(ud->settings, "volume_label", label); + ghb_dict_set_string(ud->globals, "volume_label", label); g_free(label); } else { label = _("No Title Found"); gtk_label_set_text (GTK_LABEL(widget), label); - ghb_dict_set_string(ud->settings, "volume_label", label); + ghb_dict_set_string(ud->globals, "volume_label", label); return FALSE; } return TRUE; @@ -1158,7 +1158,7 @@ show_settings(GhbValue *settings) void ghb_load_settings(signal_user_data_t * ud) { - GhbValue *preset; + const char *fullname; gboolean preset_modified; static gboolean busy = FALSE; @@ -1166,7 +1166,7 @@ ghb_load_settings(signal_user_data_t * ud) return; busy = TRUE; - preset = ghb_dict_get_value(ud->settings, "preset"); + fullname = ghb_dict_get_string(ud->settings, "PresetFullName"); preset_modified = ghb_dict_get_bool(ud->settings, "preset_modified"); if (preset_modified) { @@ -1175,10 +1175,23 @@ ghb_load_settings(signal_user_data_t * ud) else { ghb_dict_set_bool(ud->settings, "preset_reload", TRUE); - ghb_select_preset(ud->builder, preset); + ghb_select_preset(ud->builder, fullname); ghb_dict_set_bool(ud->settings, "preset_reload", FALSE); } + busy = FALSE; + + ghb_load_post_settings(ud); +} + +void +ghb_load_post_settings(signal_user_data_t * ud) +{ + static gboolean busy = FALSE; + if (busy) + return; + busy = TRUE; + ud->dont_clear_presets = TRUE; ud->scale_busy = TRUE; @@ -1831,7 +1844,7 @@ set_title_settings(signal_user_data_t *ud, GhbValue *settings) else { ghb_dict_set(settings, "volume_label", ghb_value_dup( - ghb_dict_get_value(ud->settings, "volume_label"))); + ghb_dict_get_value(ud->globals, "volume_label"))); } ghb_dict_set_int(settings, "scale_width", title->geometry.width - title->crop[2] - title->crop[3]); @@ -1909,7 +1922,7 @@ static void load_all_titles(signal_user_data_t *ud, int titleindex) { gint ii, count; - GhbValue *preset, *preset_path = NULL; + GhbValue *preset; GhbValue *settings_array; const hb_title_t *title; @@ -1924,28 +1937,21 @@ load_all_titles(signal_user_data_t *ud, int titleindex) preset = ghb_get_current_preset(ud); if (preset != NULL) { - preset_path = ghb_get_current_preset_path(ud); - } - else - { - preset = ud->settings; + ghb_preset_to_settings(ud->settings, preset); + ghb_value_free(&preset); } for (ii = 0; ii < count; ii++) { int index; - GhbValue *settings = ghb_dict_new(); + GhbValue *settings = ghb_value_dup(ud->settings); title = hb_list_item(list, ii); index = (title != NULL) ? title->index : -1; - ghb_settings_init(settings, "Initialization"); - ghb_preset_to_settings(settings, preset); - ghb_dict_set(settings, "preset", ghb_value_dup(preset_path)); ghb_dict_set_int(settings, "title", index); set_title_settings(ud, settings); ghb_array_append(settings_array, settings); } - ghb_value_free(&preset_path); if (titleindex < 0 || titleindex >= count) { titleindex = 0; @@ -2755,20 +2761,18 @@ static void submit_job(signal_user_data_t *ud, GhbValue *settings) { static gint unique_id = 1; - gchar *type, *modified, *preset; - const GhbValue *path; + gchar *type, *modified; + const char *name; GhbValue *js; gboolean preset_modified; g_debug("submit_job"); if (settings == NULL) return; preset_modified = ghb_dict_get_bool(settings, "preset_modified"); - path = ghb_dict_get_value(settings, "preset"); - preset = ghb_preset_path_string(path); - type = ghb_preset_is_custom() ? "Custom " : ""; + name = ghb_dict_get_string(settings, "PresetFullName"); + type = ghb_dict_get_int(settings, "Type") == 1 ? "Custom " : ""; modified = preset_modified ? "Modified " : ""; - ghb_log("%s%sPreset: %s", modified, type, preset); - g_free(preset); + ghb_log("%s%sPreset: %s", modified, type, name); ghb_dict_set_int(settings, "job_unique_id", unique_id); ghb_dict_set_int(settings, "job_status", GHB_QUEUE_RUNNING); @@ -3155,7 +3159,7 @@ ghb_backend_events(signal_user_data_t *ud) if (title == NULL) { gtk_label_set_text(label, _("No Title Found")); - ghb_ui_update(ud, "title", ghb_int_value(-1)); + ghb_ui_update(ud, "title", ghb_string_value("none")); } else { diff --git a/gtk/src/callbacks.h b/gtk/src/callbacks.h index 73003211e..02c8e0805 100644 --- a/gtk/src/callbacks.h +++ b/gtk/src/callbacks.h @@ -82,6 +82,7 @@ void ghb_add_all_titles(signal_user_data_t *ud); void ghb_update_title_info(signal_user_data_t *ud); void ghb_chapter_list_refresh_all(signal_user_data_t *ud); void ghb_load_settings(signal_user_data_t * ud); +void ghb_load_post_settings(signal_user_data_t * ud); void ghb_set_current_title_settings(signal_user_data_t *ud); void ghb_container_empty(GtkContainer *c); void ghb_show_container_options(signal_user_data_t *ud); diff --git a/gtk/src/data_res.gresource.xml b/gtk/src/data_res.gresource.xml index 5570e4bea..d0f75543b 100644 --- a/gtk/src/data_res.gresource.xml +++ b/gtk/src/data_res.gresource.xml @@ -2,7 +2,6 @@ <gresources> <gresource prefix="/org/handbrake/data"> <file>internal_defaults.json</file> - <file>standard_presets.json</file> <file>widget.deps</file> <file>widget_reverse.deps</file> </gresource> diff --git a/gtk/src/ghb-3.12.ui b/gtk/src/ghb-3.12.ui index 47cf3776f..74b9ba0af 100644 --- a/gtk/src/ghb-3.12.ui +++ b/gtk/src/ghb-3.12.ui @@ -841,7 +841,7 @@ libx264 authors: </child> <child> <object class="GtkMenuItem" id="presets_restore"> - <property name="label" translatable="yes">_Update Built-in Presets</property> + <property name="label" translatable="yes">_Reload Built-in Presets</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="use_underline">True</property> @@ -7568,7 +7568,7 @@ on the Video tab instead.</property> Check this if you want the queue to clean itself up by deleting completed jobs.</property> <property name="halign">start</property> <property name="draw_indicator">True</property> - <signal name="toggled" handler="advanced_video_changed_cb" swapped="no"/> + <signal name="toggled" handler="pref_changed_cb" swapped="no"/> </object> <packing> <property name="top_attach">6</property> diff --git a/gtk/src/ghb-3.14.ui b/gtk/src/ghb-3.14.ui index edd4dcdfb..101f17558 100644 --- a/gtk/src/ghb-3.14.ui +++ b/gtk/src/ghb-3.14.ui @@ -842,7 +842,7 @@ libx264 authors: </child> <child> <object class="GtkMenuItem" id="presets_restore"> - <property name="label" translatable="yes">_Update Built-in Presets</property> + <property name="label" translatable="yes">_Reload Built-in Presets</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="use_underline">True</property> @@ -7574,7 +7574,7 @@ on the Video tab instead.</property> Check this if you want the queue to clean itself up by deleting completed jobs.</property> <property name="halign">start</property> <property name="draw_indicator">True</property> - <signal name="toggled" handler="advanced_video_changed_cb" swapped="no"/> + <signal name="toggled" handler="pref_changed_cb" swapped="no"/> </object> <packing> <property name="top_attach">6</property> diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui index bf82ac57f..4ec2c5ef7 100644 --- a/gtk/src/ghb.ui +++ b/gtk/src/ghb.ui @@ -841,7 +841,7 @@ libx264 authors: </child> <child> <object class="GtkMenuItem" id="presets_restore"> - <property name="label" translatable="yes">_Update Built-in Presets</property> + <property name="label" translatable="yes">_Reload Built-in Presets</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="use_underline">True</property> @@ -7568,7 +7568,7 @@ on the Video tab instead.</property> Check this if you want the queue to clean itself up by deleting completed jobs.</property> <property name="halign">start</property> <property name="draw_indicator">True</property> - <signal name="toggled" handler="advanced_video_changed_cb" swapped="no"/> + <signal name="toggled" handler="pref_changed_cb" swapped="no"/> </object> <packing> <property name="top_attach">6</property> diff --git a/gtk/src/internal_defaults.json b/gtk/src/internal_defaults.json index 0d4fd7657..d4a24ab15 100644 --- a/gtk/src/internal_defaults.json +++ b/gtk/src/internal_defaults.json @@ -1,9 +1,21 @@ { "Globals": { "show_preview": false, - "scan_source": "" + "scan_source": "", + "volume_label": "New Video" + }, + "OneTimeInitialization": { + "title": "none" }, "Initialization": { + "AudioAllowMP3Pass": false, + "AudioAllowAACPass": false, + "AudioAllowAC3Pass": false, + "AudioAllowDTSPass": false, + "AudioAllowDTSHDPass": false, + "AudioAllowEAC3Pass": false, + "AudioAllowFLACPass": false, + "AudioAllowTRUEHDPass": false, "AudioBitrate": "192", "AudioEncoder": "copy:ac3", "AudioTrack": 0, @@ -28,16 +40,9 @@ "MetaGenre": "", "MetaDescription": "", "MetaLongDescription": "", - "preset": [ - "Regular", - "Normal" - ], + "PresetFullName": "/Regular/Normal", "preset_modified": false, "preset_reload": false, - "preset_selection": [ - "Regular", - "Normal" - ], "PictureDisplayWidth": 720, "PictureDisplayHeight": 480, "PtoPType": "chapter", @@ -46,7 +51,6 @@ "single_title": 1, "start_point": 1.0, "start_frame": -1, - "title": 0, "title_selected": false, "volume_label": "New Video", "audio_list": [], @@ -103,98 +107,5 @@ "SrtDir": "", "window_width": 1, "window_height": 1 - }, - "Presets": { - "PictureAutoCrop": true, - "ChapterMarkers": true, - "FileFormat": "mp4", - "Folder": false, - "PictureLooseCrop": false, - "PictureModulus": 2, - "PictureDeblock": 0, - "PictureDecombDeinterlace": true, - "PictureDecomb": "off", - "PictureDecombCustom": "", - "Default": false, - "PictureBottomCrop": 0, - "PictureLeftCrop": 0, - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureDeinterlace": "off", - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoisePreset": "medium", - "PictureDenoiseTune": "none", - "PictureDenoiseCustom": "", - "PictureDetelecine": "off", - "PictureDetelecineCustom": "", - "PicturePAR": "loose", - "PicturePARWidth": 853, - "PicturePARHeight": 720, - "PictureHeight": 0, - "PictureWidth": 0, - "VideoFramerate": "auto", - "VideoFramerateMode": "vfr", - "VideoGrayScale": false, - "Mp4HttpOptimize": false, - "Mp4iPodCompatible": false, - "PictureKeepRatio": true, - "AudioAllowMP3Pass": false, - "AudioAllowAACPass": false, - "AudioAllowAC3Pass": true, - "AudioAllowDTSPass": false, - "AudioAllowDTSHDPass": false, - "AudioAllowEAC3Pass": false, - "AudioAllowFLACPass": false, - "AudioAllowTRUEHDPass": false, - "AudioCopyMask": [ - "copy:ac3" - ], - "AudioEncoderFallback": "ac3", - "AudioLanguageList": [ - "und" - ], - "AudioList": [ - { - "AudioBitrate": "192", - "AudioEncoder": "copy:ac3", - "AudioTrackQualityEnable": false, - "AudioTrackQuality": -1.0, - "AudioTrackGainSlider": 0.0, - "AudioTrackDRCSlider": 0.0, - "AudioMixdown": "dpl2", - "AudioSamplerate": "auto" - } - ], - "AudioSecondaryEncoderMode": true, - "AudioTrackSelectionBehavior": "first", - "PresetDescription": "", - "PresetName": "Name Missing", - "Type": 1, - "SubtitleLanguageList": [ - "und" - ], - "SubtitleTrackSelectionBehavior": "none", - "SubtitleAddCC": false, - "SubtitleAddForeignAudioSearch": false, - "SubtitleAddForeignAudioSubtitle": false, - "SubtitleBurnBehavior": "none", - "SubtitleBurnDVDSub": false, - "SubtitleBurnBDSub": false, - "VideoTurboTwoPass": false, - "UsesPictureFilters": true, - "UsesPictureSettings": 2, - "VideoTwoPass": false, - "VideoAvgBitrate": 1800, - "VideoEncoder": "x264", - "VideoQualityType": 2, - "VideoQualitySlider": 0.59999999999999998, - "x264Option": "", - "VideoPreset": "medium", - "VideoTune": "", - "VideoProfile": "", - "VideoLevel": "", - "x264UseAdvancedOptions": false, - "VideoOptionExtra": "" } } diff --git a/gtk/src/main.c b/gtk/src/main.c index 5b60252fe..de5b3813f 100644 --- a/gtk/src/main.c +++ b/gtk/src/main.c @@ -798,7 +798,6 @@ int main(int argc, char *argv[]) { signal_user_data_t *ud; - GhbValue *preset; GError *error = NULL; GOptionContext *context; @@ -1011,13 +1010,15 @@ main(int argc, char *argv[]) ghb_settings_init(ud->prefs, "Preferences"); ghb_settings_init(ud->globals, "Globals"); ghb_settings_init(ud->settings, "Initialization"); + ghb_settings_init(ud->settings, "OneTimeInitialization"); // Load user preferences file ghb_prefs_load(ud); // Store user preferences into ud->prefs ghb_prefs_to_settings(ud->prefs); - // Load all settings with default preset values - ghb_settings_init(ud->settings, "Presets"); + int logLevel = ghb_dict_get_int(ud->prefs, "LoggingLevel"); + ghb_backend_init(logLevel); + // Load the presets files ghb_presets_load(ud); // Note that ghb_preset_to_settings(ud->settings) is called when @@ -1028,9 +1029,6 @@ main(int argc, char *argv[]) // Note that ghb_settings_to_ui(ud->settings) happens when initial // empty title is initialized. - gint logLevel; - logLevel = ghb_dict_get_int(ud->prefs, "LoggingLevel"); - ghb_backend_init(logLevel); if (ghb_dict_get_bool(ud->prefs, "hbfd")) { @@ -1040,16 +1038,11 @@ main(int argc, char *argv[]) ghb_dvd_set_current(source, ud); // Populate the presets tree view - ghb_presets_list_init(ud, NULL, 0); + ghb_presets_list_init(ud, NULL); // Get the first preset name if (arg_preset != NULL) { - preset = ghb_parse_preset_path(arg_preset); - if (preset) - { - ghb_select_preset(ud->builder, preset); - ghb_value_free(&preset); - } + ghb_select_preset(ud->builder, arg_preset); } else { diff --git a/gtk/src/presets.c b/gtk/src/presets.c index 5c2825c7e..7f9c5f8c9 100644 --- a/gtk/src/presets.c +++ b/gtk/src/presets.c @@ -27,7 +27,6 @@ #include "audiohandler.h" #include "subtitlehandler.h" #include "hb-backend.h" -#include "plist.h" #include "resources.h" #include "presets.h" #include "values.h" @@ -38,484 +37,126 @@ enum { + PRESETS_INVALID = -1, PRESETS_BUILTIN = 0, PRESETS_CUSTOM }; -static GhbValue *presetsPlistFile = NULL; -static GhbValue *presetsPlist = NULL; -static GhbValue *prefsPlist = NULL; +static GhbValue *prefsDict = NULL; static gboolean prefs_modified = FALSE; -static void store_presets(void); static void store_prefs(void); +static void store_presets(void); -static void -dict_clean(GhbValue *dict, GhbValue *template) +hb_preset_index_t* +ghb_tree_get_index(GtkTreeModel *store, GtkTreeIter *iter) { - GhbValue *tmp = ghb_value_dup(dict); - GhbDictIter iter; - const gchar *key; - GhbValue *val; - GhbValue *template_val; + GtkTreePath *treepath; + int *indices, len; + hb_preset_index_t *path; - iter = ghb_dict_iter_init(tmp); - while (ghb_dict_iter_next(tmp, &iter, &key, &val)) - { - template_val = ghb_dict_get(template, key); - if (template_val == NULL) - { - ghb_dict_remove(dict, key); - } - if (ghb_value_type(val) == GHB_DICT && - ghb_value_type(template_val) == GHB_DICT) - { - val = ghb_dict_get(dict, key); - dict_clean(val, template_val); - } - if (ghb_value_type(val) == GHB_ARRAY && - ghb_value_type(template_val) == GHB_ARRAY && - ghb_array_len(template_val) > 0) - { - template_val = ghb_array_get(template_val, 0); - if (ghb_value_type(template_val) == GHB_DICT) - { - val = ghb_dict_get(dict, key); - int count = ghb_array_len(val); - int ii; - for (ii = 0; ii < count; ii++) - { - GhbValue *array_val; - array_val = ghb_array_get(val, ii); - if (ghb_value_type(array_val) == GHB_DICT) - { - dict_clean(array_val, template_val); - } - } - } - } - } - ghb_value_free(&tmp); + treepath = gtk_tree_model_get_path(store, iter); + indices = gtk_tree_path_get_indices(treepath); + len = gtk_tree_path_get_depth(treepath); + path = hb_preset_index_init(indices, len); + gtk_tree_path_free(treepath); + + return path; } -gint -preset_path_cmp(gint *indices1, gint len1, gint *indices2, gint len2) +hb_preset_index_t* +ghb_tree_path_get_index(GtkTreePath *treepath) { - gint ii; - for (ii = 0; ii < len1 && ii < len2; ii++) - { - if (indices1[ii] != indices2[ii]) - return indices1[ii] - indices2[ii]; - } - return len1 - len2; + int *indices, len; + + indices = gtk_tree_path_get_indices(treepath); + len = gtk_tree_path_get_depth(treepath); + + return hb_preset_index_init(indices, len); } // This only handle limited depth GtkTreePath* -ghb_tree_path_new_from_indices(gint *indices, gint len) +ghb_tree_path_new_from_index(const hb_preset_index_t *path) { - switch (len) + if (path == NULL || path->depth == 0) + return NULL; + +#if GTK_CHECK_VERSION(3, 12, 0) + return gtk_tree_path_new_from_indicesv((int*)path->index, path->depth); +#else + switch (path->depth) { case 1: return gtk_tree_path_new_from_indices( - indices[0], -1); + path->index[0], -1); case 2: return gtk_tree_path_new_from_indices( - indices[0], indices[1], -1); + path->index[0], path->index[1], -1); case 3: return gtk_tree_path_new_from_indices( - indices[0], indices[1], indices[2], -1); + path->index[0], path->index[1], path->index[2], -1); case 4: return gtk_tree_path_new_from_indices( - indices[0], indices[1], indices[2], indices[3], -1); + path->index[0], path->index[1], path->index[2], + path->index[3], -1); case 5: return gtk_tree_path_new_from_indices( - indices[0], indices[1], indices[2], indices[3], indices[4], -1); + path->index[0], path->index[1], path->index[2], + path->index[3], path->index[4], -1); + case 6: + return gtk_tree_path_new_from_indices( + path->index[0], path->index[1], path->index[2], + path->index[3], path->index[4], path->index[5], -1); + case 7: + return gtk_tree_path_new_from_indices( + path->index[0], path->index[1], path->index[2], + path->index[3], path->index[4], path->index[5], + path->index[6], -1); + case 8: + return gtk_tree_path_new_from_indices( + path->index[0], path->index[1], path->index[2], + path->index[3], path->index[4], path->index[5], + path->index[6], path->index[7], -1); default: + g_warning("Preset path depth too deep"); return NULL; } +#endif } -GhbValue* -ghb_parse_preset_path(const gchar *path) -{ - gchar **split; - GhbValue *preset; - gint ii; - - preset = ghb_array_new(); - split = g_strsplit(path, "#", MAX_NESTED_PRESET); - for (ii = 0; split[ii] != NULL; ii++) - { - ghb_array_append(preset, ghb_string_value_new(split[ii])); - } - g_strfreev(split); - return preset; -} - -static GhbValue* -preset_path_from_indices(GhbValue *presets, gint *indices, gint len) -{ - gint ii; - GhbValue *path; - - g_debug("preset_path_from_indices"); - path = ghb_array_new(); - for (ii = 0; ii < len; ii++) - { - GhbValue *dict; - gint count, folder; - const GhbValue *name; - - count = ghb_array_len(presets); - if (indices[ii] >= count) break; - dict = ghb_array_get(presets, indices[ii]); - name = ghb_dict_get(dict, "PresetName"); - if (name) - ghb_array_append(path, ghb_value_dup(name)); - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (!folder) - break; - presets = ghb_dict_get(dict, "ChildrenArray"); - } - return path; -} - -gchar* -ghb_preset_path_string(const GhbValue *path) -{ - gint count, ii; - GString *gstr; - GhbValue *val; - gchar *str; - - gstr = g_string_new(""); - if (path != NULL) - { - count = ghb_array_len(path); - for (ii = 0; ii < count; ii++) - { - val = ghb_array_get(path, ii); - const char *tmp = ghb_value_get_string(val); - g_string_append(gstr, tmp); - if (ii < count-1) - g_string_append(gstr, "->"); - } - } - str = g_string_free(gstr, FALSE); - return str; -} - -void -dump_preset_path(const gchar *msg, const GhbValue *path) -{ - gchar *str; - - if (path) - debug_show_type (ghb_value_type(path)); - str = ghb_preset_path_string(path); - g_message("%s path: (%s)", msg, str); - g_free(str); -} - +#if 0 void -dump_preset_indices(const gchar *msg, gint *indices, gint len) +dump_preset_indices(const gchar *msg, hb_preset_index_t *path) { gint ii; - g_message("%s indices: len %d", msg, len); - for (ii = 0; ii < len; ii++) + g_message("%s indices: len %d", msg, path->depth); + for (ii = 0; ii < path->depth; ii++) { - printf("%d ", indices[ii]); + printf("%d ", path->index[ii]); } printf("\n"); } - -#if 0 -static gint -preset_path_cmp(const GhbValue *path1, const GhbValue *path2) -{ - gint count, ii; - GhbValue *val; - const gchar *str1, *str2; - gint result; - - count = ghb_array_len(path1); - ii = ghb_array_len(path2); - if (ii != count) - return ii - count; - for (ii = 0; ii < count; ii++) - { - val = ghb_array_get(path1, ii); - str1 = ghb_value_get_string(val); - val = ghb_array_get(path2, ii); - str2 = ghb_value_get_string(val); - result = strcmp(str1, str2); - if (result != 0) - return result; - } - return 0; -} #endif -static GhbValue* -presets_get_dict(GhbValue *presets, gint *indices, gint len) -{ - gint ii, count, folder; - GhbValue *dict = NULL; - - g_debug("presets_get_dict ()"); - for (ii = 0; ii < len; ii++) - { - count = ghb_array_len(presets); - if (indices[ii] >= count) return NULL; - dict = ghb_array_get(presets, indices[ii]); - if (ii < len-1) - { - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (!folder) - return NULL; - presets = ghb_dict_get(dict, "ChildrenArray"); - } - } - if (ii < len) - return NULL; - return dict; -} - -static GhbValue* -presets_get_folder(GhbValue *presets, gint *indices, gint len) -{ - gint ii, count, folder; - GhbValue *dict; - - g_debug("presets_get_folder ()"); - for (ii = 0; ii < len; ii++) - { - count = ghb_array_len(presets); - if (indices[ii] >= count) return NULL; - dict = ghb_array_get(presets, indices[ii]); - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (!folder) - break; - presets = ghb_dict_get(dict, "ChildrenArray"); - } - if (ii < len) - return NULL; - return presets; -} - -static GhbValue* -plist_get_dict(GhbValue *presets, const gchar *name) -{ - if (presets == NULL || name == NULL) return NULL; - return ghb_dict_get(presets, name); -} - -static const gchar* -preset_get_name(GhbValue *dict) -{ - return ghb_value_get_string(ghb_dict_get(dict, "PresetName")); -} - -static gboolean -preset_folder_is_open(GhbValue *dict) -{ - const GhbValue *gval; - - gval = ghb_dict_get(dict, "FolderOpen"); - if (gval != NULL) - return ghb_value_get_bool(gval); - return FALSE; -} - -gboolean -ghb_preset_folder(GhbValue *dict) -{ - return ghb_value_get_int(ghb_dict_get(dict, "Folder")); -} - -gint -ghb_preset_type(GhbValue *dict) -{ - return ghb_value_get_int(ghb_dict_get(dict, "Type")); -} - -static void -presets_remove_nth(GhbValue *presets, gint pos) -{ - gint count; - - if (presets == NULL || pos < 0) return; - count = ghb_array_len(presets); - if (pos >= count) return; - ghb_array_remove(presets, pos); -} - -gboolean -ghb_presets_remove( - GhbValue *presets, - gint *indices, - gint len) -{ - GhbValue *folder = NULL; - - folder = presets_get_folder(presets, indices, len-1); - if (folder) - presets_remove_nth(folder, indices[len-1]); - else - { - g_warning("ghb_presets_remove (): internal preset lookup error"); - return FALSE; - } - return TRUE; -} - -static void -ghb_presets_replace( - GhbValue *presets, - GhbValue *dict, - gint *indices, - gint len) -{ - GhbValue *folder = NULL; - - folder = presets_get_folder(presets, indices, len-1); - if (folder) - ghb_array_replace(folder, indices[len-1], dict); - else - { - g_warning("ghb_presets_replace (): internal preset lookup error"); - } -} - -static void -ghb_presets_insert( - GhbValue *presets, - GhbValue *dict, - gint *indices, - gint len) -{ - GhbValue *folder = NULL; - - folder = presets_get_folder(presets, indices, len-1); - if (folder) - ghb_array_insert(folder, indices[len-1], dict); - else - { - g_warning("ghb_presets_insert (): internal preset lookup error"); - } -} - -static gint -presets_find_element(GhbValue *presets, const gchar *name) -{ - GhbValue *dict; - gint count, ii; - - g_debug("presets_find_element () (%s)", name); - if (presets == NULL || name == NULL) return -1; - count = ghb_array_len(presets); - for (ii = 0; ii < count; ii++) - { - const gchar *str; - dict = ghb_array_get(presets, ii); - str = preset_get_name(dict); - if (strcmp(name, str) == 0) - { - return ii; - } - } - return -1; -} - -static gint -single_find_pos(GhbValue *presets, const gchar *name, gint type) -{ - GhbValue *dict; - gint count, ii, ptype, last; - - if (presets == NULL || name == NULL) return -1; - last = count = ghb_array_len(presets); - for (ii = 0; ii < count; ii++) - { - const gchar *str; - dict = ghb_array_get(presets, ii); - str = preset_get_name(dict); - ptype = ghb_value_get_int(ghb_dict_get(dict, "Type")); - if (strcasecmp(name, str) <= 0 && ptype == type) - { - return ii; - } - if (ptype == type) - last = ii+1; - } - return last; -} - -static gint* -presets_find_pos(const GhbValue *path, gint type, gint *len) -{ - GhbValue *nested; - GhbValue *val; - gint count, ii; - gboolean folder; - gint *indices = NULL; - const gchar *name; - GhbValue *dict; - - g_debug("presets_find_pos () "); - nested = presetsPlist; - count = ghb_array_len(path); - indices = g_malloc(MAX_NESTED_PRESET * sizeof(gint)); - for (ii = 0; ii < count-1; ii++) - { - val = ghb_array_get(path, ii); - name = ghb_value_get_string(val); - indices[ii] = presets_find_element(nested, name); - if (indices[ii] == -1) { - g_free(indices); - return NULL; - } - dict = ghb_array_get(nested, indices[ii]); - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - nested = NULL; - if (!folder) - break; - nested = ghb_dict_get(dict, "ChildrenArray"); - } - if (nested) - { - const gchar *name; - - name = ghb_value_get_string(ghb_array_get(path, count-1)); - indices[ii] = single_find_pos(nested, name, type); - ii++; - } - *len = ii; - return indices; -} - static gint preset_tree_depth(GhbValue *dict) { - gboolean folder; - - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (folder) + if (ghb_dict_get_bool(dict, "Folder")) { - gint depth = 0; - gint count, ii; + gint depth = 0; + gint count, ii; GhbValue *presets; presets = ghb_dict_get(dict, "ChildrenArray"); - count = ghb_array_len(presets); + count = ghb_array_len(presets); for (ii = 0; ii < count; ii++) { gint tmp; - dict = ghb_array_get(presets, ii); - tmp = preset_tree_depth(dict); + dict = ghb_array_get(presets, ii); + tmp = preset_tree_depth(dict); depth = MAX(depth, tmp); } return depth + 1; @@ -526,415 +167,331 @@ preset_tree_depth(GhbValue *dict) } } -static gboolean -preset_is_default(GhbValue *dict) -{ - const GhbValue *val; - - val = ghb_dict_get(dict, "Default"); - return ghb_value_get_bool(val); -} - -static void -presets_clear_default(GhbValue *presets) +void +ghb_presets_list_show_default(signal_user_data_t *ud) { - gint count, ii; - - count = ghb_array_len(presets); - for (ii = 0; ii < count; ii++) - { - GhbValue *dict; - gboolean folder; - - dict = ghb_array_get(presets, ii); - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (folder) - { - GhbValue *nested; + hb_preset_index_t *path; - nested = ghb_dict_get(dict, "ChildrenArray"); - presets_clear_default(nested); - } - else - { - if (preset_is_default(dict)) - { - ghb_dict_set(dict, "Default", ghb_bool_value_new(FALSE)); - } - } - } -} + path = hb_presets_get_default_index(); + if (path == NULL || path->depth == 0) + return; -static void -presets_customize(GhbValue *presets) -{ - gint count, ii; + GtkTreeView *treeview; + GtkTreeStore *store; + GtkTreePath *treepath; + GtkTreeIter iter; - count = ghb_array_len(presets); - for (ii = 0; ii < count; ii++) + treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); + treepath = ghb_tree_path_new_from_index(path); + if (treepath) { - GhbValue *dict; - gboolean folder; - gint ptype; - - dict = ghb_array_get(presets, ii); - - ptype = ghb_value_get_int(ghb_dict_get(dict, "Type")); - if (ptype != PRESETS_CUSTOM) - { - ghb_dict_set(dict, "Type", ghb_int_value_new(PRESETS_CUSTOM)); - } - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (folder) + if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath)) { - GhbValue *nested; - - nested = ghb_dict_get(dict, "ChildrenArray"); - presets_customize(nested); + gtk_tree_store_set(store, &iter, + 1, 800, + 2, 2 , + -1); } + gtk_tree_path_free(treepath); } + free(path); } -static gint* -presets_find_default2(GhbValue *presets, gint *len) +void +ghb_presets_list_clear_default(signal_user_data_t *ud) { - gint count, ii; - gint *indices; - - count = ghb_array_len(presets); - for (ii = 0; ii < count; ii++) - { - GhbValue *dict; - gboolean folder; - - dict = ghb_array_get(presets, ii); - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (folder) - { - GhbValue *nested; - gint pos = *len; + hb_preset_index_t *path; - nested = ghb_dict_get(dict, "ChildrenArray"); - (*len)++; - indices = presets_find_default2(nested, len); - if (indices) - { - indices[pos] = ii; - return indices; - } - else - *len = pos; - } - else - { - if (preset_is_default(dict)) - { - indices = g_malloc(MAX_NESTED_PRESET * sizeof(gint)); - indices[*len] = ii; - (*len)++; - return indices; - } - } - } - return NULL; -} + path = hb_presets_get_default_index(); + if (path == NULL || path->depth == 0) + return; -static gint* -presets_find_default(GhbValue *presets, gint *len) -{ - *len = 0; - return presets_find_default2(presets, len); -} + GtkTreeView *treeview; + GtkTreeStore *store; + GtkTreePath *treepath; + GtkTreeIter iter; -gint* -ghb_preset_indices_from_path( - GhbValue *presets, - const GhbValue *path, - gint *len) -{ - GhbValue *nested; - GhbValue *val; - gint count, ii; - gint *indices = NULL; - const gchar *name; - GhbValue *dict; - gboolean folder; - - g_debug("ghb_preset_indices_from_path () "); - nested = presets; - count = ghb_array_len(path); - if (count) - indices = g_malloc(MAX_NESTED_PRESET * sizeof(gint)); - *len = 0; - for (ii = 0; ii < count; ii++) + treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); + treepath = ghb_tree_path_new_from_index(path); + if (treepath) { - val = ghb_array_get(path, ii); - name = ghb_value_get_string(val); - indices[ii] = presets_find_element(nested, name); - if (indices[ii] == -1) - { - g_free(indices); - return NULL; - } - if (ii < count-1) + if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath)) { - dict = ghb_array_get(nested, indices[ii]); - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (!folder) - { - g_free(indices); - return NULL; - } - nested = ghb_dict_get(dict, "ChildrenArray"); + gtk_tree_store_set(store, &iter, + 1, 400, + 2, 0 , + -1); } + gtk_tree_path_free(treepath); } - *len = ii; - return indices; + free(path); } static gint -ghb_presets_get_type( - GhbValue *presets, - gint *indices, - gint len) +preset_get_type(hb_preset_index_t *path) { GhbValue *dict; - gint type = 0; - - dict = presets_get_dict(presets, indices, len); + dict = hb_preset_get(path); if (dict) { - type = ghb_preset_type(dict); + return ghb_dict_get_int(dict, "Type"); } else { - g_warning("ghb_presets_get_type (): internal preset lookup error"); + g_warning("ghb_preset_get_type (): internal preset lookup error"); + return 0; } - return type; + return 0; } static gboolean -ghb_presets_get_folder( - GhbValue *presets, - gint *indices, - gint len) +preset_is_folder(hb_preset_index_t *path) { GhbValue *dict; gboolean folder = FALSE; - dict = presets_get_dict(presets, indices, len); + dict = hb_preset_get(path); if (dict) { - folder = ghb_preset_folder(dict); - } - else - { - g_warning("ghb_presets_get_folder (): internal preset lookup error"); + folder = ghb_dict_get_bool(dict, "Folder"); } return folder; } void -presets_set_default(gint *indices, gint len) +ghb_preset_to_settings(GhbValue *settings, GhbValue *preset) { - GhbValue *dict; + // Remove troublesome x264Option + ghb_dict_remove(settings, "x264Option"); - g_debug("presets_set_default ()"); - presets_clear_default(presetsPlist); - dict = presets_get_dict(presetsPlist, indices, len); - if (dict) + // Initialize defaults + ghb_settings_init(settings, "Initialization"); + + // Initialize the ui settings from a preset + ghb_dict_copy(settings, preset); + + // Fix up all the internal settings that are derived from preset values. + ghb_dict_set_bool(settings, "PictureDeinterlaceDecomb", + !ghb_dict_get_bool(settings, "PictureDecombDeinterlace")); + + ghb_dict_set(settings, "scale_height", ghb_value_dup( + ghb_dict_get_value(settings, "PictureHeight"))); + + ghb_dict_set(settings, "scale_width", ghb_value_dup( + ghb_dict_get_value(settings, "PictureWidth"))); + + gint uses_pic; + gint vqtype; + + uses_pic = ghb_dict_get_int(settings, "UsesPictureSettings"); + vqtype = ghb_dict_get_int(settings, "VideoQualityType"); + + // "Use max" or "strict anamorphic" imply autoscale + if (uses_pic == 2) { - ghb_dict_set(dict, "Default", ghb_bool_value_new(TRUE)); + ghb_dict_set_bool(settings, "autoscale", TRUE); + } + else if (uses_pic == 1) + { + ghb_dict_set_bool(settings, "autoscale", FALSE); } - store_presets(); -} -static void -presets_set_folder_open(gboolean open, gint *indices, gint len) -{ - GhbValue *dict; + // VideoQualityType/0/1/2 - vquality_type_/target/bitrate/constant + // *note: target is no longer used + switch (vqtype) + { + case 0: + { + ghb_dict_set_bool(settings, "vquality_type_bitrate", TRUE); + ghb_dict_set_bool(settings, "vquality_type_constant", FALSE); + } break; + case 1: + { + ghb_dict_set_bool(settings, "vquality_type_bitrate", TRUE); + ghb_dict_set_bool(settings, "vquality_type_constant", FALSE); + } break; + case 2: + { + ghb_dict_set_bool(settings, "vquality_type_bitrate", FALSE); + ghb_dict_set_bool(settings, "vquality_type_constant", TRUE); + } break; + default: + { + ghb_dict_set_bool(settings, "vquality_type_bitrate", FALSE); + ghb_dict_set_bool(settings, "vquality_type_constant", TRUE); + } break; + } - g_debug("presets_set_folder_open ()"); - dict = presets_get_dict(presetsPlist, indices, len); - if (dict) + const gchar *mode = ghb_dict_get_string(settings, "VideoFramerateMode"); + if (strcmp(mode, "cfr") == 0) { - ghb_dict_set(dict, "FolderOpen", ghb_bool_value_new(open)); + ghb_dict_set_bool(settings, "VideoFramerateCFR", TRUE); + ghb_dict_set_bool(settings, "VideoFrameratePFR", FALSE); + ghb_dict_set_bool(settings, "VideoFramerateVFR", FALSE); + } + else if (strcmp(mode, "pfr") == 0) + { + ghb_dict_set_bool(settings, "VideoFramerateCFR", FALSE); + ghb_dict_set_bool(settings, "VideoFrameratePFR", TRUE); + ghb_dict_set_bool(settings, "VideoFramerateVFR", FALSE); + } + else + { + ghb_dict_set_bool(settings, "VideoFramerateCFR", FALSE); + ghb_dict_set_bool(settings, "VideoFrameratePFR", FALSE); + ghb_dict_set_bool(settings, "VideoFramerateVFR", TRUE); } -} -static void init_settings_from_dict( - GhbValue *dest, GhbValue *template, GhbValue *dict, gboolean filter); + if (ghb_dict_get_bool(settings, "x264UseAdvancedOptions")) + { + // Force preset/tune/profile/level/opts to conform to option string + ghb_dict_set_string(settings, "VideoPreset", "medium"); + ghb_dict_set_string(settings, "VideoTune", "none"); + ghb_dict_set_string(settings, "VideoProfile", "auto"); + ghb_dict_set_string(settings, "VideoLevel", "auto"); + ghb_dict_set(settings, "VideoOptionExtra", ghb_value_dup( + ghb_dict_get_value(settings, "x264Option"))); + } + else + { + ghb_dict_remove(settings, "x264Option"); + } -static void -init_settings_from_array( - GhbValue *dest, - GhbValue *template, - GhbValue *array, - gboolean filter) -{ - GhbValue *gval, *val, *new_val; - gint count, ii; + int ii, encoder; + const char * const *videoPresets; + const char *videoPreset; - if (ghb_array_len(template) == 0) + encoder = ghb_get_video_encoder(settings); + videoPresets = hb_video_encoder_get_presets(encoder); + videoPreset = ghb_dict_get_string(settings, "VideoPreset"); + for (ii = 0; videoPreset && videoPresets && videoPresets[ii]; ii++) { - if (!filter) + if (!strcasecmp(videoPreset, videoPresets[ii])) { - count = ghb_array_len(array); - for (ii = 0; ii < count; ii++) - { - val = ghb_array_get(array, ii); - ghb_array_append(dest, ghb_value_dup(val)); - } + ghb_dict_set_int(settings, "VideoPresetSlider", ii); + break; } - return; } + if (videoPreset != NULL) + ghb_dict_set_string(settings, "VideoPreset", videoPreset); - count = ghb_array_len(array); - // The first element of the template array is always the - // template for the allowed values - gval = ghb_array_get(template, 0); - for (ii = 0; ii < count; ii++) + char *videoTune; + char *tune = NULL; + char *saveptr; + char *tok; + + videoTune = g_strdup(ghb_dict_get_string(settings, "VideoTune")); + tok = strtok_r(videoTune, ",./-+", &saveptr); + ghb_dict_set_bool(settings, "x264FastDecode", FALSE); + ghb_dict_set_bool(settings, "x264ZeroLatency", FALSE); + while (tok != NULL) { - val = ghb_array_get(array, ii); - if (ghb_value_type(gval) == GHB_DICT) + if (!strcasecmp(tok, "fastdecode")) { - GhbValue *new_dict; - if (val != NULL && ghb_value_type(val) == GHB_DICT) - { - new_dict = ghb_dict_new(); - init_settings_from_dict(new_dict, gval, val, filter); - } - else - { - new_dict = ghb_value_dup(gval); - } - new_val = new_dict; + ghb_dict_set_bool(settings, "x264FastDecode", TRUE); } - else if (ghb_value_type(gval) == GHB_ARRAY) + else if (!strcasecmp(tok, "zerolatency")) { - GhbValue *new_array; - if (val != NULL && ghb_value_type(val) == GHB_ARRAY) - { - new_array = ghb_array_new(); - init_settings_from_array(new_array, gval, val, filter); - } - else - { - new_array = ghb_value_dup(gval); - } - new_val = new_array; + ghb_dict_set_bool(settings, "x264ZeroLatency", TRUE); + } + else if (tune == NULL) + { + tune = g_strdup(tok); } else { - if (val == NULL) - new_val = ghb_value_dup(gval); - else - new_val = ghb_value_dup(val); + ghb_log("Superfluous tunes! %s", tok); } - ghb_array_append(dest, new_val); + tok = strtok_r(NULL, ",./-+", &saveptr); + } + g_free(videoTune); + if (tune != NULL) + { + ghb_dict_set_string(settings, "VideoTune", tune); + g_free(tune); } -} -static void -init_settings_from_dict( - GhbValue *dest, - GhbValue *template, - GhbValue *dict, - gboolean filter) -{ - GhbDictIter iter; - const gchar *key; - GhbValue *gval, *val, *new_val; + const char *videoProfile; + videoProfile = ghb_dict_get_string(settings, "VideoProfile"); + if (videoProfile != NULL) + ghb_dict_set_string(settings, "VideoProfile", videoProfile); - iter = ghb_dict_iter_init(template); - // middle (void*) cast prevents gcc warning "defreferencing type-punned - // pointer will break strict-aliasing rules" - while (ghb_dict_iter_next(template, &iter, &key, &gval)) - { - val = NULL; - if (dict) - val = ghb_dict_get(dict, key); - if (ghb_value_type(gval) == GHB_DICT) - { - GhbValue *new_dict; - if (val != NULL && ghb_value_type(val) == GHB_DICT) - { - new_dict = ghb_dict_new(); - init_settings_from_dict(new_dict, gval, val, filter); - } - else - { - new_dict = ghb_value_dup(gval); - } - new_val = new_dict; - } - else if (ghb_value_type(gval) == GHB_ARRAY) - { - GhbValue *new_array; - if (val != NULL && ghb_value_type(val) == GHB_ARRAY) - { - new_array = ghb_array_new(); - init_settings_from_array(new_array, gval, val, filter); - } - else - { - new_array = ghb_value_dup(gval); - } - new_val = new_array; + const char *videoLevel; + videoLevel = ghb_dict_get_string(settings, "VideoLevel"); + if (videoLevel != NULL) + ghb_dict_set_string(settings, "VideoLevel", videoLevel); - } - else - { - if (val == NULL) - new_val = ghb_value_dup(gval); - else - new_val = ghb_value_dup(val); - } - ghb_dict_set(dest, key, new_val); + if (ghb_dict_get(settings, "x264OptionExtra") != NULL) + { + const char *optionExtra; + optionExtra = ghb_dict_get_string(settings, "x264OptionExtra"); + ghb_dict_set_string(settings, "VideoOptionExtra", optionExtra); } - if (filter || dict == NULL) - return; - - // If not filtering the source, copy source elements that - // were not in the template. - iter = ghb_dict_iter_init(dict); - // middle (void*) cast prevents gcc warning "defreferencing type-punned - // pointer will break strict-aliasing rules" - while (ghb_dict_iter_next(dict, &iter, &key, &gval)) + // Extract copy mask to check box booleans + GhbValue *copy_mask; + copy_mask = ghb_dict_get(preset, "AudioCopyMask"); + if (copy_mask != NULL) { - val = ghb_dict_get(template, key); - if (val == NULL) + int count = ghb_array_len(copy_mask); + int ii; + for (ii = 0; ii < count; ii++) { - ghb_dict_set(dest, key, ghb_value_dup(gval)); + GhbValue *val = ghb_array_get(copy_mask, ii); + const char *s = ghb_value_get_string(val); + int acodec = hb_audio_encoder_get_from_name(s); + switch (acodec) + { + default: + break; + case HB_ACODEC_LAME: + case HB_ACODEC_MP3_PASS: + ghb_dict_set_bool(settings, "AudioAllowMP3Pass", 1); + break; + case HB_ACODEC_CA_AAC: + case HB_ACODEC_FDK_AAC: + case HB_ACODEC_FFAAC: + case HB_ACODEC_AAC_PASS: + ghb_dict_set_bool(settings, "AudioAllowAACPass", 1); + break; + case HB_ACODEC_AC3: + case HB_ACODEC_AC3_PASS: + ghb_dict_set_bool(settings, "AudioAllowAC3Pass", 1); + break; + case HB_ACODEC_DCA: + case HB_ACODEC_DCA_PASS: + ghb_dict_set_bool(settings, "AudioAllowDTSPass", 1); + break; + case HB_ACODEC_DCA_HD: + case HB_ACODEC_DCA_HD_PASS: + ghb_dict_set_bool(settings, "AudioAllowDTSHDPass", 1); + break; + case HB_ACODEC_FFEAC3: + case HB_ACODEC_EAC3_PASS: + ghb_dict_set_bool(settings, "AudioAllowEAC3Pass", 1); + break; + case HB_ACODEC_FFFLAC: + case HB_ACODEC_FFFLAC24: + case HB_ACODEC_FLAC_PASS: + ghb_dict_set_bool(settings, "AudioAllowFLACPass", 1); + break; + case HB_ACODEC_FFTRUEHD: + case HB_ACODEC_TRUEHD_PASS: + ghb_dict_set_bool(settings, "AudioAllowTRUEHDPass", 1); + break; + } } } } -void -ghb_preset_to_settings(GhbValue *settings, GhbValue *preset) -{ - // Initialize the ui from presets file. - GhbValue *internal; - - // Get key list from internal default presets. This way we do not - // load any unknown keys. - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); - if (internalPlist == NULL) return; - internal = plist_get_dict(internalPlist, "Presets"); - if (preset == NULL) - preset = internal; - - ghb_dict_remove(settings, "x264Option"); - init_settings_from_dict(settings, preset, NULL, TRUE); -} - // Initialization order of some widgets matter because the value of // these widgets are used to establich limits on the values that // other widgets are allowed to take. // // So make sure these get initialized first. -static const char *widget_priority_list[] = +static const char *widget_priority_list[] = { "preview_count", "PtoPType", @@ -947,11 +504,11 @@ static const char *widget_priority_list[] = void ghb_settings_to_ui(signal_user_data_t *ud, GhbValue *dict) { - GhbDictIter iter; + GhbDictIter iter; const gchar *key; - GhbValue *gval; - int ii; - GhbValue *tmp = ghb_value_dup(dict); + GhbValue *gval; + int ii; + GhbValue *tmp = ghb_value_dup(dict); if (dict == NULL) return; @@ -974,136 +531,61 @@ ghb_settings_to_ui(signal_user_data_t *ud, GhbValue *dict) ghb_value_free(&tmp); } -static GhbValue *current_preset = NULL; - -gboolean -ghb_preset_is_custom() -{ - const GhbValue *val; - - if (current_preset == NULL) return FALSE; - val = ghb_dict_get(current_preset, "Type"); - return (ghb_value_get_int(val) == 1); -} - -void -ghb_set_preset_settings_from_indices( - signal_user_data_t *ud, - gint *indices, - gint len) -{ - GhbValue *dict = NULL; - gint fallback[2] = {0, -1}; - - if (indices) - dict = presets_get_dict(presetsPlist, indices, len); - if (dict == NULL) - { - indices = fallback; - len = 1; - dict = presets_get_dict(presetsPlist, indices, len); - } - if (dict == NULL) - { - ghb_preset_to_settings(ud->settings, NULL); - current_preset = NULL; - } - else - { - GhbValue *path; - gboolean folder; - - current_preset = dict; - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (folder) - ghb_preset_to_settings(ud->settings, NULL); - else - ghb_preset_to_settings(ud->settings, dict); - path = preset_path_from_indices(presetsPlist, indices, len); - ghb_dict_set(ud->settings, "preset", ghb_value_dup(path)); - ghb_value_free(&path); - } -} - -static const GhbValue* -curr_preset_get_value(const gchar *key) -{ - if (current_preset == NULL) return NULL; - return ghb_dict_get(current_preset, key); -} - -void -ghb_update_from_preset( - signal_user_data_t *ud, - const gchar *key) -{ - const GhbValue *gval; - - g_debug("ghb_update_from_preset() %s", key); - gval = curr_preset_get_value(key); - if (gval != NULL) - { - ghb_ui_update(ud, key, gval); - } -} - static void -ghb_select_preset2( - GtkBuilder *builder, - gint *indices, - gint len) +select_preset2(GtkBuilder *builder, hb_preset_index_t *path) { - GtkTreeView *treeview; + GtkTreeView *treeview; GtkTreeSelection *selection; - GtkTreeModel *store; - GtkTreeIter iter; - GtkTreePath *path; + GtkTreeModel *store; + GtkTreeIter iter; + GtkTreePath *treepath; - g_debug("ghb_select_preset2()"); - treeview = GTK_TREE_VIEW(GHB_WIDGET(builder, "presets_list")); + if (path == NULL || path->depth == 0) + return; + + treeview = GTK_TREE_VIEW(GHB_WIDGET(builder, "presets_list")); selection = gtk_tree_view_get_selection (treeview); - store = gtk_tree_view_get_model (treeview); - path = ghb_tree_path_new_from_indices(indices, len); - if (path) + store = gtk_tree_view_get_model (treeview); + treepath = ghb_tree_path_new_from_index(path); + if (treepath != NULL) { - if (gtk_tree_model_get_iter(store, &iter, path)) + gtk_tree_view_expand_to_path(treeview, treepath); + if (gtk_tree_model_get_iter(store, &iter, treepath)) { - gtk_tree_selection_select_iter (selection, &iter); + gtk_tree_selection_select_iter(selection, &iter); } else { if (gtk_tree_model_get_iter_first(store, &iter)) - gtk_tree_selection_select_iter (selection, &iter); + gtk_tree_selection_select_iter(selection, &iter); } - gtk_tree_path_free(path); + gtk_tree_path_free(treepath); } } void -ghb_select_preset(GtkBuilder *builder, const GhbValue *path) +ghb_select_preset(GtkBuilder *builder, const char *name) { - gint *indices, len; + hb_preset_index_t *path; - g_debug("ghb_select_preset()"); - indices = ghb_preset_indices_from_path(presetsPlist, path, &len); - if (indices) + path = hb_preset_search_index(name, 1); + if (path != NULL) { - ghb_select_preset2(builder, indices, len); - g_free(indices); + select_preset2(builder, path); + free(path); } } void ghb_select_default_preset(GtkBuilder *builder) { - gint *indices, len; + hb_preset_index_t *path; - g_debug("ghb_select_default_preset()"); - indices = presets_find_default(presetsPlist, &len); - if (indices) + path = hb_presets_get_default_index(); + if (path != NULL) { - ghb_select_preset2(builder, indices, len); - g_free(indices); + select_preset2(builder, path); + g_free(path); } } @@ -1111,12 +593,12 @@ gchar* ghb_get_user_config_dir(gchar *subdir) { const gchar *dir; - gchar *config; + gchar *config; dir = g_get_user_config_dir(); if (!g_file_test(dir, G_FILE_TEST_IS_DIR)) { - dir = g_get_home_dir(); + dir = g_get_home_dir(); config = g_strdup_printf ("%s/.ghb", dir); if (!g_file_test(config, G_FILE_TEST_IS_DIR)) g_mkdir (config, 0755); @@ -1130,7 +612,7 @@ ghb_get_user_config_dir(gchar *subdir) if (subdir) { gchar **split; - gint ii; + gint ii; split = g_strsplit(subdir, G_DIR_SEPARATOR_S, -1); for (ii = 0; split[ii] != NULL; ii++) @@ -1154,7 +636,7 @@ write_config_file(const gchar *name, GhbValue *dict) gchar *config, *path; config = ghb_get_user_config_dir(NULL); - path = g_strdup_printf ("%s/%s", config, name); + path = g_strdup_printf ("%s/%s", config, name); g_free(config); ghb_json_write_file(path, dict); g_free(path); @@ -1166,32 +648,52 @@ ghb_write_settings_file(const gchar *path, GhbValue *dict) ghb_json_write_file(path, dict); } -static void -store_plist(const gchar *name, GhbValue *plist) +static int +presets_add_config_file(const gchar *name) { - gchar *config, *path; + gchar *config, *path; + hb_value_t *preset; config = ghb_get_user_config_dir(NULL); - path = g_strdup_printf ("%s/%s", config, name); + path = g_strdup_printf ("%s/%s", config, name); g_free(config); - ghb_plist_write_file(path, plist); + if (!g_file_test(path, G_FILE_TEST_IS_REGULAR)) + return -1; + preset = hb_presets_read_file(path); g_free(path); + if (preset != NULL) + { + hb_presets_add(preset); + + int hb_major, hb_minor, hb_micro; + int major, minor, micro; + hb_presets_version(preset, &major, &minor, µ); + hb_presets_current_version(&hb_major, &hb_minor, &hb_micro); + if (major != hb_major || minor != hb_minor || micro != hb_micro) + { + // Reload hb builtin presets + hb_presets_builtin_update(); + store_presets(); + } + return 0; + } + return -1; } static GhbValue* read_config_file(const gchar *name) { - gchar *config, *path; + gchar *config, *path; GhbValue *gval = NULL; config = ghb_get_user_config_dir(NULL); - path = g_strdup_printf ("%s/%s", config, name); + path = g_strdup_printf ("%s/%s", config, name); g_free(config); if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) { gval = ghb_json_parse_file(path); if (gval == NULL) - gval = ghb_plist_parse_file(path); + gval = hb_plist_parse_file(path); } g_free(path); return gval; @@ -1206,11 +708,13 @@ ghb_read_settings_file(const gchar *path) { gval = ghb_json_parse_file(path); if (gval == NULL) - gval = ghb_plist_parse_file(path); + gval = hb_plist_parse_file(path); } return gval; } +#if 0 +// Currently unused, but keeping around just in case... gboolean ghb_lock_file(const gchar *name) { @@ -1232,22 +736,22 @@ ghb_lock_file(const gchar *name) return 1; #endif } +#endif void ghb_write_pid_file() { #if !defined(_WIN32) gchar *config, *path; - pid_t pid; - FILE *fp; - int fd; - - pid = getpid(); + pid_t pid; + FILE *fp; + int fd; + pid = getpid(); config = ghb_get_user_config_dir(NULL); - path = g_strdup_printf ("%s/ghb.pid.%d", config, pid); + path = g_strdup_printf ("%s/ghb.pid.%d", config, pid); + fp = g_fopen(path, "w"); - fp = g_fopen(path, "w"); fprintf(fp, "%d\n", pid); fclose(fp); @@ -1259,42 +763,26 @@ ghb_write_pid_file() #endif } -void -ghb_unlink_pid_file(int pid) -{ - gchar *config, *path; - - config = ghb_get_user_config_dir(NULL); - path = g_strdup_printf ("%s/ghb.pid.%d", config, pid); - - if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) - { - g_unlink(path); - } - - g_free(config); - g_free(path); -} - int ghb_find_pid_file() { const gchar *file; - gchar *config; + gchar *config; config = ghb_get_user_config_dir(NULL); if (g_file_test(config, G_FILE_TEST_IS_DIR)) { - GDir *gdir = g_dir_open(config, 0, NULL); + GDir *gdir; + gdir = g_dir_open(config, 0, NULL); file = g_dir_read_name(gdir); while (file) { if (strncmp(file, "ghb.pid.", 8) == 0) { gchar *path; - pid_t my_pid; - int pid; + pid_t my_pid; + int pid; sscanf(file, "ghb.pid.%d", &pid); my_pid = getpid(); @@ -1346,7 +834,7 @@ remove_config_file(const gchar *name) gchar *config, *path; config = ghb_get_user_config_dir(NULL); - path = g_strdup_printf ("%s/%s", config, name); + path = g_strdup_printf ("%s/%s", config, name); if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) { g_unlink(path); @@ -1356,33 +844,6 @@ remove_config_file(const gchar *name) } void -ghb_prefs_save(GhbValue *settings) -{ - GhbValue *dict; - GhbValue *pref_dict; - GhbDictIter iter; - const gchar *key; - const GhbValue *value; - - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); - dict = plist_get_dict(internalPlist, "Preferences"); - if (dict == NULL) return; - pref_dict = plist_get_dict(prefsPlist, "Preferences"); - if (pref_dict == NULL) return; - iter = ghb_dict_iter_init(dict); - while (ghb_dict_iter_next(dict, &iter, &key, NULL)) - { - value = ghb_dict_get_value(settings, key); - if (value != NULL) - { - ghb_dict_set(pref_dict, key, ghb_value_dup(value)); - } - } - store_prefs(); - prefs_modified = FALSE; -} - -void ghb_pref_save(GhbValue *settings, const gchar *key) { const GhbValue *value, *value2; @@ -1391,7 +852,7 @@ ghb_pref_save(GhbValue *settings, const gchar *key) if (value != NULL) { GhbValue *dict; - dict = plist_get_dict(prefsPlist, "Preferences"); + dict = ghb_dict_get(prefsDict, "Preferences"); if (dict == NULL) return; value2 = ghb_dict_get(dict, key); if (ghb_value_cmp(value, value2) != 0) @@ -1412,7 +873,7 @@ ghb_pref_set(GhbValue *settings, const gchar *key) if (value != NULL) { GhbValue *dict; - dict = plist_get_dict(prefsPlist, "Preferences"); + dict = ghb_dict_get(prefsDict, "Preferences"); if (dict == NULL) return; value2 = ghb_dict_get(dict, key); if (ghb_value_cmp(value, value2) != 0) @@ -1436,35 +897,23 @@ ghb_prefs_store(void) void ghb_settings_init(GhbValue *settings, const char *name) { - GhbValue *internal; - GhbDictIter iter; - const gchar *key; - GhbValue *gval; + GhbValue *internal; - g_debug("ghb_settings_init"); - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); + GhbValue *internalDict = ghb_resource_get("internal-defaults"); // 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, name); - iter = ghb_dict_iter_init(internal); - // middle (void*) cast prevents gcc warning "defreferencing type-punned - // pointer will break strict-aliasing rules" - while (ghb_dict_iter_next(internal, &iter, &key, &gval)) - { - ghb_dict_set(settings, key, ghb_value_dup(gval)); - } + internal = ghb_dict_get(internalDict, name); + ghb_dict_copy(settings, internal); } void ghb_settings_close() { - if (presetsPlist) - ghb_value_free(&presetsPlist); - if (prefsPlist) - ghb_value_free(&prefsPlist); + if (prefsDict) + ghb_value_free(&prefsDict); } #if defined(_WIN32) @@ -1498,47 +947,35 @@ FindFirstCDROM(void) void ghb_prefs_load(signal_user_data_t *ud) { - GhbValue *dict, *internal; - GhbDictIter iter; - const gchar *key; - GhbValue *gval; - - g_debug("ghb_prefs_load"); - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); - prefsPlist = read_config_file("preferences"); - if (prefsPlist == NULL) - prefsPlist = ghb_dict_new(); - dict = plist_get_dict(prefsPlist, "Preferences"); - internal = plist_get_dict(internalPlist, "Preferences"); - if (dict == NULL && internal) - { - dict = ghb_dict_new(); - ghb_dict_set(prefsPlist, "Preferences", dict); + GhbValue *dict, *internal; + GhbValue *internalDict; - // Get defaults from internal defaults - iter = ghb_dict_iter_init(internal); - // middle (void*) cast prevents gcc warning "defreferencing type-punned - // pointer will break strict-aliasing rules" - while (ghb_dict_iter_next(internal, &iter, &key, &gval)) - { - ghb_dict_set(dict, key, ghb_value_dup(gval)); - } + internalDict = ghb_resource_get("internal-defaults"); + prefsDict = read_config_file("preferences"); + if (prefsDict == NULL) + prefsDict = ghb_dict_new(); + dict = ghb_dict_get(prefsDict, "Preferences"); + internal = ghb_dict_get(internalDict, "Preferences"); + if (dict == NULL && internal != NULL) + { + dict = ghb_value_dup(internal); + ghb_dict_set(prefsDict, "Preferences", dict); const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); if (dir == NULL) { dir = "."; } - ghb_dict_set(dict, "ExportDirectory", ghb_string_value_new(dir)); + ghb_dict_set_string(dict, "ExportDirectory", dir); dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS); if (dir == NULL) { dir = "."; } - ghb_dict_set(dict, "destination_dir", ghb_string_value_new(dir)); + ghb_dict_set_string(dict, "destination_dir", dir); - ghb_dict_set(dict, "SrtDir", ghb_string_value_new(dir)); + ghb_dict_set_string(dict, "SrtDir", dir); #if defined(_WIN32) gchar *source; @@ -1547,7 +984,7 @@ ghb_prefs_load(signal_user_data_t *ud) { source = g_strdup("C:" G_DIR_SEPARATOR_S); } - ghb_dict_set(dict, "default_source", ghb_string_value_new(source)); + ghb_dict_set_string(dict, "default_source", source); g_free(source); #endif store_prefs(); @@ -1558,34 +995,29 @@ void ghb_prefs_to_settings(GhbValue *settings) { // Initialize the ui from presets file. - GhbValue *internal, *dict; + GhbValue *dict; - if (prefsPlist == NULL) + if (prefsDict == NULL) return; - // Get key list from internal default presets. This way we do not - // load any unknown keys. - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); - if (internalPlist == NULL) return; - internal = plist_get_dict(internalPlist, "Preferences"); - dict = plist_get_dict(prefsPlist, "Preferences"); // 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(settings, internal, dict, TRUE); + dict = ghb_dict_get(prefsDict, "Preferences"); + ghb_dict_copy(settings, dict); } static const gchar* -get_preset_color(gint type, gboolean folder) +get_preset_color(gint type, gboolean is_folder) { const gchar *color; if (type == PRESETS_CUSTOM) { color = "DimGray"; - if (folder) + if (is_folder) { color = "black"; } @@ -1593,7 +1025,7 @@ get_preset_color(gint type, gboolean folder) else { color = "blue"; - if (folder) + if (is_folder) { color = "Navy"; } @@ -1602,238 +1034,247 @@ get_preset_color(gint type, gboolean folder) } void -ghb_presets_list_init( - signal_user_data_t *ud, - gint *indices, - gint len) +ghb_presets_list_init(signal_user_data_t *ud, const hb_preset_index_t *path) { - GtkTreeView *treeview; - GtkTreeIter iter, titer, *piter; + hb_preset_index_t *next_path; + GhbValue *folder; + GtkTreeView *treeview; + GtkTreeStore *store; + GtkTreePath *parent_path; + GtkTreeIter iter, *piter; + gint count, ii; - GtkTreeStore *store; - const gchar *preset; - GtkTreePath *parent_path; - const gchar *description; - gboolean def; - gint count, ii; - GhbValue *dict; - gint *more_indices; - GhbValue *presets = NULL; - - g_debug("ghb_presets_list_init ()"); - more_indices = g_malloc((len+1)*sizeof(gint)); - memcpy(more_indices, indices, len*sizeof(gint)); - presets = presets_get_folder(presetsPlist, indices, len); - if (presets == NULL) + if (path == NULL) + { + hb_preset_index_t *p = hb_preset_index_init(NULL, 0); + ghb_presets_list_init(ud, p); + free(p); + return; + } + next_path = hb_preset_index_dup(path); + folder = hb_presets_get_folder_children(path); + if (folder == NULL) { g_warning(_("Failed to find parent folder when adding child.")); - g_free(more_indices); + g_free(next_path); return; } - count = ghb_array_len(presets); - treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); - store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); - parent_path = ghb_tree_path_new_from_indices(indices, len); - if (parent_path) + treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); + parent_path = ghb_tree_path_new_from_index(path); + if (parent_path != NULL) { - gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &titer, parent_path); - piter = &titer; + GtkTreeIter tmp_iter; + gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &tmp_iter, parent_path); + piter = &tmp_iter; gtk_tree_path_free(parent_path); } else { piter = NULL; } + count = ghb_array_len(folder); + next_path->depth++; for (ii = 0; ii < count; ii++) { + GhbValue *dict; + const gchar *name; const gchar *color; - gint type; - gboolean folder; + gint type; + const gchar *description; + gboolean is_folder; + gboolean def; + + next_path->index[next_path->depth-1] = ii; // Additional settings, add row - dict = ghb_array_get(presets, ii); - preset = preset_get_name(dict); - more_indices[len] = ii; - def = preset_is_default(dict); + dict = ghb_array_get(folder, ii); + name = ghb_dict_get_string(dict, "PresetName"); + description = ghb_dict_get_string(dict, "PresetDescription"); + type = ghb_dict_get_int(dict, "Type"); + is_folder = ghb_dict_get_bool(dict, "Folder"); + def = ghb_dict_get_bool(dict, "Default"); + color = get_preset_color(type, is_folder); - description = ghb_value_get_string( - ghb_dict_get(dict, "PresetDescription")); gtk_tree_store_append(store, &iter, piter); - type = ghb_preset_type(dict); - folder = ghb_preset_folder(dict); - color = get_preset_color(type, folder); - gtk_tree_store_set(store, &iter, 0, preset, + gtk_tree_store_set(store, &iter, + 0, name, 1, def ? 800 : 400, - 2, def ? 2 : 0, + 2, def ? 2 : 0, 3, color, 4, description, 5, type == PRESETS_BUILTIN ? 0 : 1, -1); - if (def && piter) - { - GtkTreePath *path; - GtkTreeIter ppiter; - - if (gtk_tree_model_iter_parent( - GTK_TREE_MODEL(store), &ppiter, piter)) - { - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &ppiter); - gtk_tree_view_expand_row(treeview, path, FALSE); - gtk_tree_path_free(path); - } - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), piter); - gtk_tree_view_expand_row(treeview, path, FALSE); - gtk_tree_path_free(path); - } - if (folder) + if (is_folder) { - ghb_presets_list_init(ud, more_indices, len+1); - if (preset_folder_is_open(dict)) + ghb_presets_list_init(ud, next_path); + if (ghb_dict_get_bool(dict, "FolderOpen")) { GtkTreePath *path; - - if (piter != NULL) - { - path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), piter); - gtk_tree_view_expand_row(treeview, path, FALSE); - gtk_tree_path_free(path); - } path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); - gtk_tree_view_expand_row(treeview, path, FALSE); + gtk_tree_view_expand_to_path(treeview, path); gtk_tree_path_free(path); } } } - g_free(more_indices); + g_free(next_path); + if (path == NULL) + { + ghb_presets_list_show_default(ud); + } +} + +static void +presets_list_clear(signal_user_data_t *ud) +{ + GtkTreeView *treeview; + GtkTreeModel *store; + GtkTreeIter iter; + gboolean valid; + + treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + store = gtk_tree_view_get_model(treeview); + valid = gtk_tree_model_get_iter_first(store, &iter); + while (valid) + { + gtk_tree_store_remove(GTK_TREE_STORE(store), &iter); + valid = gtk_tree_model_get_iter_first(store, &iter); + } +} + +void +ghb_presets_list_reinit(signal_user_data_t *ud) +{ + presets_list_clear(ud); + ghb_presets_list_init(ud, NULL); } static void presets_list_update_item( - signal_user_data_t *ud, - gint *indices, - gint len, - gboolean recurse) + signal_user_data_t *ud, + const hb_preset_index_t *path, + gboolean recurse) { - GtkTreeView *treeview; + GhbValue *dict; + GtkTreeView *treeview; GtkTreeStore *store; - GtkTreeIter iter; - GtkTreePath *treepath; - const gchar *name; - const gchar *description; - gint type; - gboolean def, folder; - GhbValue *dict; - const gchar *color; - - g_debug("presets_list_update_item ()"); - dict = presets_get_dict(presetsPlist, indices, len); + GtkTreePath *treepath; + GtkTreeIter iter; + const gchar *name; + const gchar *description; + gint type; + gboolean is_folder; + gboolean def; + const gchar *color; + + dict = hb_preset_get(path); if (dict == NULL) return; + treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); - store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); - treepath = ghb_tree_path_new_from_indices(indices, len); + store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); + treepath = ghb_tree_path_new_from_index(path); gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath); + // Additional settings, add row - name = preset_get_name(dict); - def = preset_is_default(dict); - - description = ghb_value_get_string(ghb_dict_get(dict, "PresetDescription")); - type = ghb_preset_type(dict); - folder = ghb_preset_folder(dict); - color = get_preset_color(type, folder); - gtk_tree_store_set(store, &iter, 0, name, + name = ghb_dict_get_string(dict, "PresetName"); + description = ghb_dict_get_string(dict, "PresetDescription"); + type = ghb_dict_get_int(dict, "Type"); + is_folder = ghb_dict_get_bool(dict, "Folder"); + def = ghb_dict_get_bool(dict, "Default"); + color = get_preset_color(type, is_folder); + + gtk_tree_store_set(store, &iter, + 0, name, 1, def ? 800 : 400, - 2, def ? 2 : 0, + 2, def ? 2 : 0, 3, color, 4, description, 5, type == PRESETS_BUILTIN ? 0 : 1, -1); - if (recurse && folder) + if (recurse && is_folder) { - ghb_presets_list_init(ud, indices, len); + ghb_presets_list_init(ud, path); } } static void -presets_list_insert( - signal_user_data_t *ud, - gint *indices, - gint len) -{ - GtkTreeView *treeview; - GtkTreeIter iter, titer, *piter; - GtkTreeStore *store; - const gchar *preset; - const gchar *description; - gint type; - gboolean def, folder; - gint count; - GhbValue *presets; - GtkTreePath *parent_path; - GhbValue *dict; - const gchar *color; - - g_debug("presets_list_insert ()"); - treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); - store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); - presets = presets_get_folder(presetsPlist, indices, len-1); - if (presets == NULL) +presets_list_append(signal_user_data_t *ud, const hb_preset_index_t *path) +{ + hb_preset_index_t *folder_path; + hb_value_t *dict; + GtkTreeView *treeview; + GtkTreeStore *store; + GtkTreePath *folder_treepath; + GtkTreeIter iter, *piter; + const gchar *name; + const gchar *description; + gint type; + gboolean is_folder; + gboolean def; + const gchar *color; + + folder_path = hb_preset_index_dup(path); + folder_path->depth--; + + dict = hb_preset_get(path); + if (dict == NULL) { - g_warning(_("Failed to find parent folder while adding child.")); + g_message("Ack! Desync between presets and preset list"); return; } - parent_path = ghb_tree_path_new_from_indices(indices, len-1); - if (parent_path) + + treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); + + folder_treepath = ghb_tree_path_new_from_index(folder_path); + if (folder_treepath != NULL) { - gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &titer, parent_path); - piter = &titer; - gtk_tree_path_free(parent_path); + GtkTreeIter tmp_iter; + gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &tmp_iter, + folder_treepath); + piter = &tmp_iter; + gtk_tree_path_free(folder_treepath); } else { piter = NULL; } - count = ghb_array_len(presets); - if (indices[len-1] >= count) - return; + // Additional settings, add row - dict = ghb_array_get(presets, indices[len-1]); - preset = preset_get_name(dict); - def = preset_is_default(dict); - - description = ghb_value_get_string(ghb_dict_get(dict, "PresetDescription")); - gtk_tree_store_insert(store, &iter, piter, indices[len-1]); - type = ghb_preset_type(dict); - folder = ghb_preset_folder(dict); - color = get_preset_color(type, folder); - gtk_tree_store_set(store, &iter, 0, preset, + name = ghb_dict_get_string(dict, "PresetName"); + description = ghb_dict_get_string(dict, "PresetDescription"); + type = ghb_dict_get_int(dict, "Type"); + is_folder = ghb_dict_get_bool(dict, "Folder"); + def = ghb_dict_get_bool(dict, "Default"); + color = get_preset_color(type, is_folder); + + gtk_tree_store_append(store, &iter, piter); + gtk_tree_store_set(store, &iter, + 0, name, 1, def ? 800 : 400, - 2, def ? 2 : 0, + 2, def ? 2 : 0, 3, color, 4, description, 5, type == PRESETS_BUILTIN ? 0 : 1, -1); - if (folder) + if (is_folder) { - ghb_presets_list_init(ud, indices, len); + ghb_presets_list_init(ud, path); } } static void -presets_list_remove( - signal_user_data_t *ud, - gint *indices, - gint len) +presets_list_remove(signal_user_data_t *ud, hb_preset_index_t *path) { - GtkTreeView *treeview; - GtkTreePath *treepath; - GtkTreeIter iter; + GtkTreeView *treeview; + GtkTreePath *treepath; + GtkTreeIter iter; GtkTreeStore *store; - g_debug("presets_list_remove ()"); treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); - store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); - treepath = ghb_tree_path_new_from_indices(indices, len); + store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); + treepath = ghb_tree_path_new_from_index(path); if (treepath) { if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath)) @@ -1842,63 +1283,25 @@ presets_list_remove( } } -static void -remove_std_presets(signal_user_data_t *ud) -{ - gint count, ii; - gint indices = 0; - - count = ghb_array_len(presetsPlist); - for (ii = count-1; ii >= 0; ii--) - { - GhbValue *dict; - gint ptype; - - dict = ghb_array_get(presetsPlist, ii); - ptype = ghb_value_get_int(ghb_dict_get(dict, "Type")); - if (ptype == PRESETS_BUILTIN) - { - if (ghb_presets_remove(presetsPlist, &indices, 1)) - { - presets_list_remove(ud, &indices, 1); - } - } - } -} - void ghb_save_queue(GhbValue *queue) { - pid_t pid; - char *name; + pid_t pid; + char *name; - pid = getpid(); + pid = getpid(); name = g_strdup_printf ("queue.%d", pid); write_config_file(name, queue); g_free(name); } GhbValue* -ghb_load_queue() -{ - GhbValue *queue; - pid_t pid; - char *name; - - pid = getpid(); - name = g_strdup_printf ("queue.%d", pid); - queue = read_config_file(name); - g_free(name); - return queue; -} - -GhbValue* ghb_load_old_queue(int pid) { GhbValue *queue; - char *name; + char *name; - name = g_strdup_printf ("queue.%d", pid); + name = g_strdup_printf ("queue.%d", pid); queue = read_config_file(name); g_free(name); return queue; @@ -1914,963 +1317,157 @@ ghb_remove_old_queue_file(int pid) g_free(name); } -void -ghb_remove_queue_file() -{ - pid_t pid; - char *name; - - pid = getpid(); - name = g_strdup_printf ("queue.%d", pid); - remove_config_file(name); - g_free(name); -} - -typedef struct -{ - const gchar *mac_val; - const gchar *lin_val; -} value_map_t; - -value_map_t deint_xlat[] = -{ - {"0", "off"}, - {"1", "custom"}, - {"2", "fast"}, - {"3", "slow"}, - {"4", "slower"}, - {"5", "bob"}, - {NULL, NULL} -}; - -value_map_t denoise_xlat[] = -{ - {"0", "off"}, - {"1", "custom"}, - {"2", "light"}, - {"3", "medium"}, - {"4", "strong"}, - {"5", "ultralight"}, - {NULL, NULL} -}; - -value_map_t detel_xlat[] = -{ - {"0", "off"}, - {"1", "custom"}, - {"2", "default"}, - {NULL, NULL} -}; - -value_map_t decomb_xlat[] = -{ - {"0", "off"}, - {"1", "custom"}, - {"2", "default"}, - {"3", "fast"}, - {"4", "bob"}, - {NULL, NULL} -}; - -static GhbValue* -export_value_video_framerate(GhbValue *lin_val) -{ - GhbValue *sval = NULL; - gchar *str; - const gchar *fr; - - str = ghb_value_get_string_xform(lin_val); - fr = hb_video_framerate_get_name(hb_video_framerate_get_from_name(str)); - g_free(str); - if (fr != NULL) - sval = ghb_string_value_new(fr); - - return sval; -} - -static GhbValue* -export_value_audio_samplerate(GhbValue *lin_val) -{ - GhbValue *sval = NULL; - gchar *str; - const gchar *sr; - - str = ghb_value_get_string_xform(lin_val); - sr = hb_audio_samplerate_get_name(hb_audio_samplerate_get_from_name(str)); - g_free(str); - if (sr != NULL) - sval = ghb_string_value_new(sr); - - return sval; -} - -static GhbValue* -export_value_mixdown(GhbValue *lin_val) -{ - GhbValue *sval = NULL; - const gchar *str; - const gchar *mix; - - str = ghb_value_get_string(lin_val); - mix = hb_mixdown_get_short_name(hb_mixdown_get_from_name(str)); - if (mix != NULL) - sval = ghb_string_value_new(mix); - - return sval; -} - -static GhbValue* -export_value_video_encoder(GhbValue *lin_val) -{ - GhbValue *sval = NULL; - const gchar *str; - const gchar *enc; - - str = ghb_value_get_string(lin_val); - enc = hb_video_encoder_get_short_name(hb_video_encoder_get_from_name(str)); - if (enc != NULL) - sval = ghb_string_value_new(enc); - - return sval; -} - -static GhbValue* -export_value_audio_encoder(GhbValue *lin_val) -{ - GhbValue *sval = NULL; - const gchar *str; - const gchar *enc; - - str = ghb_value_get_string(lin_val); - enc = hb_audio_encoder_get_short_name(hb_audio_encoder_get_from_name(str)); - if (enc != NULL) - sval = ghb_string_value_new(enc); - - return sval; -} - -static GhbValue* -export_value_container(GhbValue *lin_val) -{ - GhbValue *sval = NULL; - const gchar *str; - const gchar *mux; - - str = ghb_value_get_string(lin_val); - mux = hb_container_get_short_name(hb_container_get_from_name(str)); - if (mux != NULL) - sval = ghb_string_value_new(mux); - - return sval; -} - -// Translate values for compatibility with other platforms -static void -export_value_xlat(GhbValue *dict) -{ - GhbValue *lin_val, *gval; - const gchar *key; - - // Convert PictureModulus to correct data type - key = "PictureModulus"; - lin_val = ghb_dict_get(dict, key); - gval = ghb_value_xform(lin_val, GHB_INT); - if (gval) - ghb_dict_set(dict, key, gval); - key = "VideoEncoder"; - lin_val = ghb_dict_get(dict, key); - gval = export_value_video_encoder(lin_val); - if (gval) - ghb_dict_set(dict, key, gval); - key = "FileFormat"; - lin_val = ghb_dict_get(dict, key); - gval = export_value_container(lin_val); - if (gval) - ghb_dict_set(dict, key, gval); - key = "VideoFramerate"; - lin_val = ghb_dict_get(dict, key); - gval = export_value_video_framerate(lin_val); - if (gval) - ghb_dict_set(dict, key, gval); - - gint count, ii; - GhbValue *alist; - GhbValue *adict; - - key = "AudioEncoderFallback"; - lin_val = ghb_dict_get(dict, key); - gval = export_value_audio_encoder(lin_val); - if (gval) - ghb_dict_set(dict, key, gval); - - alist = ghb_dict_get(dict, "AudioList"); - count = ghb_array_len(alist); - for (ii = 0; ii < count; ii++) - { - adict = ghb_array_get(alist, ii); - key = "AudioEncoder"; - lin_val = ghb_dict_get(adict, key); - gval = export_value_audio_encoder(lin_val); - if (gval) - ghb_dict_set(adict, key, gval); - key = "AudioSamplerate"; - lin_val = ghb_dict_get(adict, key); - gval = export_value_audio_samplerate(lin_val); - if (gval) - ghb_dict_set(adict, key, gval); - key = "AudioMixdown"; - lin_val = ghb_dict_get(adict, key); - gval = export_value_mixdown(lin_val); - if (gval) - ghb_dict_set(adict, key, gval); - } -} - - -static GhbValue* -import_value_xlat2( - GhbValue *defaults, - value_map_t *value_map, - const gchar *key, - GhbValue *mac_val) -{ - GhbValue *gval, *def_val; - - if (mac_val == NULL) return NULL; - def_val = ghb_dict_get(defaults, key); - if (def_val) - { - gint ii; - gchar *str; - GhbValue *sval; - - str = ghb_value_get_string_xform(mac_val); - for (ii = 0; value_map[ii].mac_val; ii++) - { - if (strcmp(str, value_map[ii].mac_val) == 0 || - strcmp(str, value_map[ii].lin_val) == 0) - { - sval = ghb_string_value_new(value_map[ii].lin_val); - g_free(str); - gval = ghb_value_xform(sval, ghb_value_type(def_val)); - if (gval == NULL) - { - g_warning("can't transform"); - ghb_value_free(&sval); - return NULL; - } - ghb_value_free(&sval); - return gval; - } - } - g_free(str); - return ghb_value_dup(def_val); - } - else - { - gint ii; - gchar *str; - GhbValue *sval; - - str = ghb_value_get_string_xform(mac_val); - for (ii = 0; value_map[ii].mac_val; ii++) - { - if (strcmp(str, value_map[ii].mac_val) == 0 || - strcmp(str, value_map[ii].lin_val) == 0) - { - sval = ghb_string_value_new(value_map[ii].lin_val); - g_free(str); - gval = ghb_value_xform(sval, ghb_value_type(mac_val)); - if (gval == NULL) - { - g_warning("can't transform"); - ghb_value_free(&sval); - return NULL; - } - ghb_value_free(&sval); - return gval; - } - } - g_free(str); - } - return NULL; -} - -static GhbValue* -import_value_video_framerate(GhbValue *mac_val) -{ - GhbValue *sval = NULL; - gchar *str; - const gchar *fr; - - str = ghb_value_get_string_xform(mac_val); - fr = hb_video_framerate_get_name(hb_video_framerate_get_from_name(str)); - g_free(str); - - if (fr != NULL) - sval = ghb_string_value_new(fr); - - return sval; -} - -static GhbValue* -import_value_audio_samplerate(GhbValue *mac_val) -{ - GhbValue *sval = NULL; - gchar *str; - const gchar *sr; - - str = ghb_value_get_string_xform(mac_val); - sr = hb_audio_samplerate_get_name(hb_audio_samplerate_get_from_name(str)); - g_free(str); - - if (sr != NULL) - sval = ghb_string_value_new(sr); - - return sval; -} - -static GhbValue* -import_value_mixdown(GhbValue *mac_val) -{ - GhbValue *sval = NULL; - const gchar *str; - const gchar *mix; - - str = ghb_value_get_string(mac_val); - mix = hb_mixdown_get_short_name(hb_mixdown_get_from_name(str)); - - if (mix != NULL) - sval = ghb_string_value_new(mix); - - return sval; -} - -static GhbValue* -import_value_video_encoder(GhbValue *mac_val) -{ - GhbValue *sval = NULL; - const gchar *str; - const gchar *enc; - - str = ghb_value_get_string(mac_val); - enc = hb_video_encoder_get_short_name(hb_video_encoder_get_from_name(str)); - - if (enc != NULL) - sval = ghb_string_value_new(enc); - - return sval; -} - -static GhbValue* -import_value_audio_encoder(GhbValue *mac_val) -{ - GhbValue *sval = NULL; - const gchar *str; - const gchar *enc; - - str = ghb_value_get_string(mac_val); - enc = hb_audio_encoder_get_short_name(hb_audio_encoder_get_from_name(str)); - - if (enc != NULL) - sval = ghb_string_value_new(enc); - - return sval; -} - -static GhbValue* -import_value_container(GhbValue *mac_val) -{ - GhbValue *sval = NULL; - const gchar *str; - const gchar *mux; - - str = ghb_value_get_string(mac_val); - mux = hb_container_get_short_name(hb_container_get_from_name(str)); - - if (mux != NULL) - sval = ghb_string_value_new(mux); - - return sval; -} - -static void -import_value_xlat(GhbValue *dict) -{ - GhbValue *defaults, *mac_val, *gval; - const gchar *key; - - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); - defaults = plist_get_dict(internalPlist, "Presets"); - key = "VideoEncoder"; - mac_val = ghb_dict_get(dict, key); - gval = import_value_video_encoder(mac_val); - if (gval) - ghb_dict_set(dict, key, gval); - key = "FileFormat"; - mac_val = ghb_dict_get(dict, key); - gval = import_value_container(mac_val); - if (gval) - ghb_dict_set(dict, key, gval); - key = "VideoFramerate"; - mac_val = ghb_dict_get(dict, key); - gval = import_value_video_framerate(mac_val); - if (gval) - ghb_dict_set(dict, key, gval); - key = "PictureDetelecine"; - mac_val = ghb_dict_get(dict, key); - gval = import_value_xlat2(defaults, detel_xlat, key, mac_val); - if (gval) - ghb_dict_set(dict, key, gval); - key = "PictureDecomb"; - mac_val = ghb_dict_get(dict, key); - gval = import_value_xlat2(defaults, decomb_xlat, key, mac_val); - if (gval) - ghb_dict_set(dict, key, gval); - key = "PictureDeinterlace"; - mac_val = ghb_dict_get(dict, key); - gval = import_value_xlat2(defaults, deint_xlat, key, mac_val); - if (gval) - ghb_dict_set(dict, key, gval); - key = "PictureDenoisePreset"; - mac_val = ghb_dict_get(dict, key); - gval = import_value_xlat2(defaults, denoise_xlat, key, mac_val); - if (gval) - ghb_dict_set(dict, key, gval); - - ghb_dict_remove(dict, "Subtitles"); - ghb_dict_remove(dict, "SubtitlesForced"); - - gint count, ii; - GhbValue *alist; - GhbValue *adict; - GhbValue *adefaults; - GhbValue *adeflist; - - key = "AudioEncoderFallback"; - mac_val = ghb_dict_get(dict, key); - gval = import_value_audio_encoder(mac_val); - if (gval) - ghb_dict_set(dict, key, gval); - - adeflist = ghb_dict_get(defaults, "AudioList"); - if (adeflist) - { - adefaults = ghb_array_get(adeflist, 0); - alist = ghb_dict_get(dict, "AudioList"); - count = ghb_array_len(alist); - for (ii = 0; ii < count; ii++) - { - adict = ghb_array_get(alist, ii); - key = "AudioEncoder"; - mac_val = ghb_dict_get(adict, key); - gval = import_value_audio_encoder(mac_val); - if (gval == NULL) - gval = ghb_value_dup(ghb_dict_get(adefaults, key)); - if (gval) - ghb_dict_set(adict, key, gval); - key = "AudioSamplerate"; - mac_val = ghb_dict_get(adict, key); - gval = import_value_audio_samplerate(mac_val); - if (gval == NULL) - gval = ghb_value_dup(ghb_dict_get(adefaults, key)); - if (gval) - ghb_dict_set(adict, key, gval); - key = "AudioMixdown"; - mac_val = ghb_dict_get(adict, key); - gval = import_value_mixdown(mac_val); - if (gval == NULL) - gval = ghb_value_dup(ghb_dict_get(adefaults, key)); - if (gval) - ghb_dict_set(adict, key, gval); - - mac_val = ghb_dict_get(adict, "AudioTrackDRCSlider"); - if (mac_val != NULL) - { - gdouble drc; - drc = ghb_value_get_double(mac_val); - if (drc < 1.0) - { - ghb_dict_set(adict, "AudioTrackDRCSlider", - ghb_double_value_new(0.0)); - } - } - } - } -} - +// Translate internal values to preset key, value pairs static GhbValue* -import_xlat_preset(GhbValue *user_preset) +settings_to_preset(GhbValue *settings) { - GhbValue *dict, *internal; - - g_debug("import_xlat_preset ()"); - - dict = ghb_dict_new(); - - // First, initialize the preset with defaults. - // Then import user presets over top of defaults - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); - internal = plist_get_dict(internalPlist, "Presets"); - init_settings_from_dict(dict, internal, user_preset, FALSE); - - // Initialize the AudioLanguageList from preferences PreferredLanguage - // and translate old AudioDUB preference option if found - GhbValue *list = ghb_dict_get(dict, "AudioLanguageList"); - if (list == NULL) - { - list = ghb_array_new(); - ghb_dict_set(dict, "AudioLanguageList", list); - } - if (ghb_array_len(list) == 0) - { - GhbValue *prefs = plist_get_dict(prefsPlist, "Preferences"); - GhbValue *gdub = ghb_dict_get(prefs, "AudioDUB"); - GhbValue *glang = ghb_dict_get(prefs, "PreferredLanguage"); - const char *lang = NULL; - if (glang != NULL) - { - lang = ghb_value_get_string(glang); - } - if (gdub != NULL && !ghb_value_get_bool(gdub)) - { - if (lang == NULL || strncmp(lang, "und", 4)) - { - ghb_array_append(list, ghb_string_value_new("und")); - } - } - if (glang != NULL) - { - ghb_array_append(list, ghb_value_dup(glang)); - } - } - - // Initialize the SubtitleLanguageList from preferences PreferredLanguage - // and translate old AudioDUB preference option if found - list = ghb_dict_get(dict, "SubtitleLanguageList"); - if (list == NULL) - { - list = ghb_array_new(); - ghb_dict_set(dict, "SubtitleLanguageList", list); - } - if (ghb_array_len(list) == 0) - { - GhbValue *prefs = plist_get_dict(prefsPlist, "Preferences"); - GhbValue *val = ghb_dict_get(prefs, "PreferredLanguage"); - if (val != NULL) - { - ghb_array_append(list, ghb_value_dup(val)); - - val = ghb_dict_get(prefs, "AudioDUB"); - if (val != NULL && !ghb_value_get_bool(val)) - { - ghb_dict_set(dict, - "SubtitleAddForeignAudioSubtitle", - ghb_bool_value_new(TRUE)); - } - } - } + GhbValue *preset = ghb_value_dup(settings); - GhbValue *addCC = ghb_dict_get(dict, "SubtitleAddCC"); - if (addCC == NULL) - { - GhbValue *prefs = plist_get_dict(prefsPlist, "Preferences"); - GhbValue *val = ghb_dict_get(prefs, "AddCC"); - if (val != NULL) - { - ghb_dict_set(dict, "SubtitleAddCC", - ghb_value_dup(val)); - } - } - - import_value_xlat(dict); - - // Fix up all the internal settings that are derived from preset values. - ghb_dict_set_bool(dict, "PictureDeinterlaceDecomb", - !ghb_dict_get_bool(dict, "PictureDecombDeinterlace")); - - ghb_dict_set(dict, "scale_height", ghb_value_dup( - ghb_dict_get_value(dict, "PictureHeight"))); - - ghb_dict_set(dict, "scale_width", ghb_value_dup( - ghb_dict_get_value(dict, "PictureWidth"))); - - gint uses_pic; - gint vqtype; - - uses_pic = ghb_dict_get_int(dict, "UsesPictureSettings"); - vqtype = ghb_dict_get_int(dict, "VideoQualityType"); - - // "Use max" or "strict anamorphic" imply autoscale - if (uses_pic == 2) - { - ghb_dict_set_bool(dict, "autoscale", TRUE); - } - else if (uses_pic == 1) - { - ghb_dict_set_bool(dict, "autoscale", FALSE); - } - - // VideoQualityType/0/1/2 - vquality_type_/target/bitrate/constant - // *note: target is no longer used - switch (vqtype) - { - case 0: - { - ghb_dict_set_bool(dict, "vquality_type_bitrate", TRUE); - ghb_dict_set_bool(dict, "vquality_type_constant", FALSE); - } break; - case 1: - { - ghb_dict_set_bool(dict, "vquality_type_bitrate", TRUE); - ghb_dict_set_bool(dict, "vquality_type_constant", FALSE); - } break; - case 2: - { - ghb_dict_set_bool(dict, "vquality_type_bitrate", FALSE); - ghb_dict_set_bool(dict, "vquality_type_constant", TRUE); - } break; - default: - { - ghb_dict_set_bool(dict, "vquality_type_bitrate", FALSE); - ghb_dict_set_bool(dict, "vquality_type_constant", TRUE); - } break; - } - - const gchar *mode = ghb_dict_get_string(dict, "VideoFramerateMode"); - if (strcmp(mode, "cfr") == 0) - { - ghb_dict_set_bool(dict, "VideoFramerateCFR", TRUE); - ghb_dict_set_bool(dict, "VideoFrameratePFR", FALSE); - ghb_dict_set_bool(dict, "VideoFramerateVFR", FALSE); - } - else if (strcmp(mode, "pfr") == 0) - { - ghb_dict_set_bool(dict, "VideoFramerateCFR", FALSE); - ghb_dict_set_bool(dict, "VideoFrameratePFR", TRUE); - ghb_dict_set_bool(dict, "VideoFramerateVFR", FALSE); - } - else - { - ghb_dict_set_bool(dict, "VideoFramerateCFR", FALSE); - ghb_dict_set_bool(dict, "VideoFrameratePFR", FALSE); - ghb_dict_set_bool(dict, "VideoFramerateVFR", TRUE); - } - - if (ghb_dict_get_bool(dict, "x264UseAdvancedOptions")) - { - // Force preset/tune/profile/level/opts to conform to option string - ghb_dict_set_string(dict, "VideoPreset", "medium"); - ghb_dict_set_string(dict, "VideoTune", "none"); - ghb_dict_set_string(dict, "VideoProfile", "auto"); - ghb_dict_set_string(dict, "VideoLevel", "auto"); - ghb_dict_set(dict, "VideoOptionExtra", ghb_value_dup( - ghb_dict_get_value(dict, "x264Option"))); - } - else - { - ghb_dict_remove(dict, "x264Option"); - } - - int encoder = ghb_get_video_encoder(dict); - const char * const *videoPresets; - videoPresets = hb_video_encoder_get_presets(encoder); - const char *videoPreset; - if (ghb_dict_get(user_preset, "x264Preset") != NULL) - videoPreset = ghb_dict_get_string(dict, "x264Preset"); - else - videoPreset = ghb_dict_get_string(dict, "VideoPreset"); - int ii; - for (ii = 0; videoPreset && videoPresets && videoPresets[ii]; ii++) - { - if (!strcasecmp(videoPreset, videoPresets[ii])) - { - ghb_dict_set_int(dict, "VideoPresetSlider", ii); - break; - } - } - if (videoPreset != NULL) - ghb_dict_set_string(dict, "VideoPreset", videoPreset); - - char *videoTune; - if (ghb_dict_get(user_preset, "x264Tune") != NULL) - videoTune = g_strdup(ghb_dict_get_string(dict, "x264Tune")); - else - videoTune = g_strdup(ghb_dict_get_string(dict, "VideoTune")); - char *tune = NULL; - char *saveptr; - char * tok = strtok_r(videoTune, ",./-+", &saveptr); - ghb_dict_set_bool(dict, "x264FastDecode", FALSE); - ghb_dict_set_bool(dict, "x264ZeroLatency", FALSE); - while (tok != NULL) - { - if (!strcasecmp(tok, "fastdecode")) - { - ghb_dict_set_bool(dict, "x264FastDecode", TRUE); - } - else if (!strcasecmp(tok, "zerolatency")) - { - ghb_dict_set_bool(dict, "x264ZeroLatency", TRUE); - } - else if (tune == NULL) - { - tune = g_strdup(tok); - } - else - { - ghb_log("Superfluous tunes! %s", tok); - } - tok = strtok_r(NULL, ",./-+", &saveptr); - } - g_free(videoTune); - if (tune != NULL) - { - ghb_dict_set_string(dict, "VideoTune", tune); - g_free(tune); - } - - const char *videoProfile; - if (ghb_dict_get(user_preset, "x264Profile") != NULL) - videoProfile = ghb_dict_get_string(dict, "x264Profile"); - else - videoProfile = ghb_dict_get_string(dict, "VideoProfile"); - if (videoProfile != NULL) - ghb_dict_set_string(dict, "VideoProfile", videoProfile); - - const char *videoLevel; - if (ghb_dict_get(user_preset, "x264Level") != NULL) - videoLevel = ghb_dict_get_string(dict, "x264Level"); - else - videoLevel = ghb_dict_get_string(dict, "VideoLevel"); - if (videoLevel != NULL) - ghb_dict_set_string(dict, "VideoLevel", videoLevel); + gboolean autoscale, br, constant; - if (ghb_dict_get(user_preset, "x264OptionExtra") != NULL) + ghb_dict_set_bool(preset, "Default", 0); + ghb_dict_set_int(preset, "Type", PRESETS_CUSTOM); + if (!ghb_dict_get_bool(preset, "PictureWidthEnable")) { - const char *optionExtra; - optionExtra = ghb_dict_get_string(dict, "x264OptionExtra"); - ghb_dict_set_string(dict, "VideoOptionExtra", optionExtra); + ghb_dict_remove(preset, "PictureWidth"); } - - return dict; -} - -static void -import_xlat_presets(GhbValue *presets) -{ - gint count, ii; - GhbValue *dict; - gboolean folder; - - g_debug("import_xlat_presets ()"); - if (presets == NULL) return; - count = ghb_array_len(presets); - for (ii = 0; ii < count; ii++) + if (!ghb_dict_get_bool(preset, "PictureHeightEnable")) { - dict = ghb_array_get(presets, ii); - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (folder) - { - GhbValue *nested; - - nested = ghb_dict_get(dict, "ChildrenArray"); - import_xlat_presets(nested); - } - else - { - GhbValue *import_dict = import_xlat_preset(dict); - ghb_array_replace(presets, ii, import_dict); - } + ghb_dict_remove(preset, "PictureHeight"); } -} - -// Translate internal values to preset key, value pairs -static void -export_xlat_preset(GhbValue *dict) -{ - gboolean autoscale, br, constant; - - g_debug("export_xlat_prest ()"); - autoscale = ghb_value_get_bool(ghb_dict_get(dict, "autoscale")); - br = ghb_value_get_bool( - ghb_dict_get(dict, "vquality_type_bitrate")); - constant = ghb_value_get_bool( - ghb_dict_get(dict, "vquality_type_constant")); + autoscale = !ghb_dict_get_bool(preset, "PictureWidthEnable") && + !ghb_dict_get_bool(preset, "PictureHeightEnable"); + br = ghb_dict_get_bool(preset, "vquality_type_bitrate"); + constant = ghb_dict_get_bool(preset, "vquality_type_constant"); if (autoscale) { - ghb_dict_set(dict, "UsesPictureSettings", ghb_int_value_new(2)); + ghb_dict_set_int(preset, "UsesPictureSettings", 2); } else { - ghb_dict_set(dict, "UsesPictureSettings", ghb_int_value_new(1)); + ghb_dict_set_int(preset, "UsesPictureSettings", 1); } // VideoQualityType/0/1/2 - vquality_type_/target/bitrate/constant // *note: target is no longer used if (br) { - ghb_dict_set(dict, "VideoQualityType", ghb_int_value_new(1)); + ghb_dict_set_int(preset, "VideoQualityType", 1); } else if (constant) { - ghb_dict_set(dict, "VideoQualityType", ghb_int_value_new(2)); + ghb_dict_set_int(preset, "VideoQualityType", 2); } - if (ghb_value_get_bool(ghb_dict_get(dict, "VideoFramerateCFR"))) + if (ghb_dict_get_bool(preset, "VideoFramerateCFR")) { - ghb_dict_set(dict, "VideoFramerateMode", ghb_string_value_new("cfr")); + ghb_dict_set_string(preset, "VideoFramerateMode", "cfr"); } - else if (ghb_value_get_bool(ghb_dict_get(dict, "VideoFrameratePFR"))) + else if (ghb_dict_get_bool(preset, "VideoFrameratePFR")) { - ghb_dict_set(dict, "VideoFramerateMode", ghb_string_value_new("pfr")); + ghb_dict_set_string(preset, "VideoFramerateMode", "pfr"); } else { - ghb_dict_set(dict, "VideoFramerateMode", ghb_string_value_new("vfr")); + ghb_dict_set_string(preset, "VideoFramerateMode", "vfr"); } - if (ghb_value_get_int(ghb_dict_get(dict, "PictureDeblock")) < 5) + if (ghb_dict_get_int(preset, "PictureDeblock") < 5) { - ghb_dict_set(dict, "PictureDeblock", ghb_int_value_new(0)); + ghb_dict_set_int(preset, "PictureDeblock", 0); } GhbValue *alist, *adict; gint count, ii; - alist = ghb_dict_get(dict, "AudioList"); + alist = ghb_dict_get(preset, "AudioList"); count = ghb_array_len(alist); for (ii = 0; ii < count; ii++) { gdouble drc; adict = ghb_array_get(alist, ii); - drc = ghb_value_get_double( - ghb_dict_get(adict, "AudioTrackDRCSlider")); + drc = ghb_dict_get_double(adict, "AudioTrackDRCSlider"); if (drc < 1.0) { - ghb_dict_set(adict, "AudioTrackDRCSlider", - ghb_double_value_new(0.0)); + ghb_dict_set_double(adict, "AudioTrackDRCSlider", 0.0); } } GhbValue *copy_mask = ghb_array_new(); - if (ghb_value_get_bool(ghb_dict_get(dict, "AudioAllowMP3Pass"))) + if (ghb_dict_get_bool(preset, "AudioAllowMP3Pass")) { ghb_array_append(copy_mask, ghb_string_value_new("copy:mp3")); } - if (ghb_value_get_bool(ghb_dict_get(dict, "AudioAllowAACPass"))) + if (ghb_dict_get_bool(preset, "AudioAllowAACPass")) { ghb_array_append(copy_mask, ghb_string_value_new("copy:aac")); } - if (ghb_value_get_bool(ghb_dict_get(dict, "AudioAllowAC3Pass"))) + if (ghb_dict_get_bool(preset, "AudioAllowAC3Pass")) { ghb_array_append(copy_mask, ghb_string_value_new("copy:ac3")); } - if (ghb_value_get_bool(ghb_dict_get(dict, "AudioAllowDTSPass"))) + if (ghb_dict_get_bool(preset, "AudioAllowDTSPass")) { ghb_array_append(copy_mask, ghb_string_value_new("copy:dts")); } - if (ghb_value_get_bool(ghb_dict_get(dict, "AudioAllowDTSHDPass"))) + if (ghb_dict_get_bool(preset, "AudioAllowDTSHDPass")) { ghb_array_append(copy_mask, ghb_string_value_new("copy:dtshd")); } - if (ghb_value_get_bool(ghb_dict_get(dict, "AudioAllowEAC3Pass"))) + if (ghb_dict_get_bool(preset, "AudioAllowEAC3Pass")) { ghb_array_append(copy_mask, ghb_string_value_new("copy:eac3")); } - if (ghb_value_get_bool(ghb_dict_get(dict, "AudioAllowFLACPass"))) + if (ghb_dict_get_bool(preset, "AudioAllowFLACPass")) { ghb_array_append(copy_mask, ghb_string_value_new("copy:flac")); } - if (ghb_value_get_bool(ghb_dict_get(dict, "AudioAllowTRUEHDPass"))) + if (ghb_dict_get_bool(preset, "AudioAllowTRUEHDPass")) { ghb_array_append(copy_mask, ghb_string_value_new("copy:truehd")); } - ghb_dict_set(dict, "AudioCopyMask", copy_mask); + ghb_dict_set(preset, "AudioCopyMask", copy_mask); - if (ghb_value_get_bool(ghb_dict_get(dict, "x264UseAdvancedOptions"))) + if (ghb_dict_get_bool(preset, "x264UseAdvancedOptions")) { - ghb_dict_remove(dict, "VideoPreset"); - ghb_dict_remove(dict, "VideoTune"); - ghb_dict_remove(dict, "VideoProfile"); - ghb_dict_remove(dict, "VideoLevel"); - ghb_dict_remove(dict, "VideoOptionExtra"); + ghb_dict_remove(preset, "VideoPreset"); + ghb_dict_remove(preset, "VideoTune"); + ghb_dict_remove(preset, "VideoProfile"); + ghb_dict_remove(preset, "VideoLevel"); + ghb_dict_remove(preset, "VideoOptionExtra"); } - const char *tune = ghb_value_get_string(ghb_dict_get(dict, "VideoTune")); + const char *tune = ghb_dict_get_string(preset, "VideoTune"); if (tune != NULL) { GString *str = g_string_new(""); char *tunes; g_string_append_printf(str, "%s", tune); - if (ghb_value_get_bool(ghb_dict_get(dict, "x264FastDecode"))) + if (ghb_dict_get_bool(preset, "x264FastDecode")) { g_string_append_printf(str, ",%s", "fastdecode"); } - if (ghb_value_get_bool(ghb_dict_get(dict, "x264ZeroLatency"))) + if (ghb_dict_get_bool(preset, "x264ZeroLatency")) { g_string_append_printf(str, ",%s", "zerolatency"); } tunes = g_string_free(str, FALSE); - ghb_dict_set(dict, "VideoTune", ghb_string_value_new(tunes)); + ghb_dict_set_string(preset, "VideoTune", tunes); g_free(tunes); } - // Remove everything from dist that isn't in "Presets" - GhbValue *internal; - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); - internal = plist_get_dict(internalPlist, "Presets"); - dict_clean(dict, internal); - - export_value_xlat(dict); -} - -static void export_xlat_presets(GhbValue *presets); - -static void -export_xlat_dict(GhbValue *dict) -{ - gboolean folder; - folder = ghb_value_get_bool(ghb_dict_get(dict, "Folder")); - if (folder) - { - GhbValue *nested; - - nested = ghb_dict_get(dict, "ChildrenArray"); - export_xlat_presets(nested); - } - else - { - export_xlat_preset(dict); - } -} + GhbValue *in_val, *out_val; -static void -export_xlat_presets(GhbValue *presets) -{ - gint count, ii; - GhbValue *dict; + // Convert PictureModulus to correct data type + in_val = ghb_dict_get(preset, "PictureModulus"); + out_val = ghb_value_xform(in_val, GHB_INT); + if (out_val != NULL) + ghb_dict_set(preset, "PictureModulus", out_val); - if (presets == NULL) return; - if (ghb_value_type(presets) == GHB_DICT) - { - export_xlat_dict(presets); - } - else if (ghb_value_type(presets) == GHB_ARRAY) - { - count = ghb_array_len(presets); - for (ii = 0; ii < count; ii++) - { - dict = ghb_array_get(presets, ii); - export_xlat_dict(dict); - } - } - else - { - g_warning("export_xlat_presets: Invalid presets format"); - } + return preset; } static guint prefs_timeout_id = 0; @@ -2878,7 +1475,7 @@ static guint prefs_timeout_id = 0; static gboolean delayed_store_prefs(gpointer data) { - write_config_file("preferences", prefsPlist); + write_config_file("preferences", prefsDict); prefs_timeout_id = 0; return FALSE; } @@ -2886,12 +1483,15 @@ delayed_store_prefs(gpointer data) static void store_presets() { - GhbValue *export; + gchar *config, *path; + hb_value_t *presets; - export = ghb_value_dup(presetsPlist); - export_xlat_presets(export); - store_plist("presets", export); - ghb_value_free(&export); + config = ghb_get_user_config_dir(NULL); + path = g_strdup_printf ("%s/%s", config, "presets.json"); + presets = hb_presets_get(); + hb_presets_write_json(presets, path); + g_free(config); + g_free(path); } static void @@ -2911,438 +1511,150 @@ store_prefs(void) } void -ghb_presets_reload(signal_user_data_t *ud) -{ - GhbValue *std_presets; - gint count, ii; - int *indices, len; - - g_debug("ghb_presets_reload()\n"); - std_presets = ghb_value_dup(ghb_resource_get("standard-presets")); - if (std_presets == NULL) return; - - remove_std_presets(ud); - indices = presets_find_default(presetsPlist, &len); - if (indices) - { - presets_clear_default(std_presets); - g_free(indices); - } - // Merge the keyfile contents into our presets - count = ghb_array_len(std_presets); - for (ii = count-1; ii >= 0; ii--) - { - GhbValue *std_dict; - GhbValue *copy_dict; - gint indices = 0; - - std_dict = ghb_array_get(std_presets, ii); - copy_dict = ghb_value_dup(std_dict); - ghb_presets_insert(presetsPlist, copy_dict, &indices, 1); - presets_list_insert(ud, &indices, 1); - } - import_xlat_presets(presetsPlist); - store_presets(); - ghb_value_free(&std_presets); -} - -static gboolean -check_old_presets(GhbValue *presetsArray) -{ - gint count, ii; - - count = ghb_array_len(presetsArray); - for (ii = count-1; ii >= 0; ii--) - { - GhbValue *dict; - GhbValue *type; - - dict = ghb_array_get(presetsArray, ii); - type = ghb_dict_get(dict, "Type"); - if (type == NULL) - return TRUE; - } - return FALSE; -} - -static void -replace_standard_presets(GhbValue *presetsArray) +ghb_presets_load(signal_user_data_t *ud) { - GhbValue *std_presets, *tmp; - int *indices, len; - gint count, ii; - - // Remove existing standard presets - count = ghb_array_len(presetsArray); - for (ii = count-1; ii >= 0; ii--) + if (presets_add_config_file("presets.json") < 0) { - GhbValue *dict; - gint ptype; - - dict = ghb_array_get(presetsArray, ii); - ptype = ghb_value_get_int(ghb_dict_get(dict, "Type")); - if (ptype == PRESETS_BUILTIN) + if (presets_add_config_file("presets") < 0) { - gint indices = 0; - ghb_presets_remove(presetsArray, &indices, 1); + g_warning("Failed to read preset file"); } } - - // Get the default standard presets - tmp = ghb_resource_get("standard-presets"); - if (tmp == NULL) return; - std_presets = ghb_value_dup(tmp); - - // Clear the default in the standard presets if one is already set - // in custom presets - indices = presets_find_default(presetsArray, &len); - if (indices) - { - presets_clear_default(std_presets); - g_free(indices); - } - - // Merge the keyfile contents into our presets - count = ghb_array_len(std_presets); - for (ii = count-1; ii >= 0; ii--) - { - GhbValue *std_dict; - GhbValue *copy_dict; - gint indices = 0; - - std_dict = ghb_array_get(std_presets, ii); - copy_dict = ghb_value_dup(std_dict); - ghb_presets_insert(presetsArray, copy_dict, &indices, 1); - } - ghb_value_free(&std_presets); } -static int -update_standard_presets(signal_user_data_t *ud, GhbValue *presetsArray) +static void +settings_save(signal_user_data_t *ud, hb_preset_index_t *path, const char *name) { - gint count, ii; + GhbValue *dict; + gboolean replace = FALSE; - count = ghb_array_len(presetsArray); - for (ii = count-1; ii >= 0; ii--) + dict = hb_preset_get(path); + if (dict != NULL) { - GhbValue *dict; - const GhbValue *gval; - gint type; - - dict = ghb_array_get(presetsArray, ii); - gval = ghb_dict_get(dict, "Type"); - if (gval == NULL) - { - // Old preset that doesn't have a Type - replace_standard_presets(presetsArray); - return 1; - } + gboolean is_folder; + int type; + const char *s; - type = ghb_value_get_int(gval); - if (type == 0) + is_folder = ghb_dict_get_bool(dict, "Folder"); + type = ghb_dict_get_int(dict, "Type"); + s = ghb_dict_get_string(dict, "PresetName"); + if (s == NULL || strcmp(s, name) || type != PRESETS_CUSTOM || is_folder) { - // TODO: check preset version -#if 0 - gint64 build; - - gval = ghb_dict_get(dict, "PresetBuildNumber"); - if (gval == NULL) - { - // Old preset that doesn't have a build number - replace_standard_presets(presetsArray); - return 1; - } - - build = ghb_value_get_int(gval); - if (build != hb_get_build(NULL)) + // Name changed or original preset was builtin or original + // was a folder. Don't replace it. + replace = FALSE; + path->depth--; + if (type != PRESETS_CUSTOM) { - // Build number does not match - replace_standard_presets(presetsArray); - return 1; + // Don't put new custom presets in a builtin folder + path->depth = 1; } -#endif - } - } - return 0; -} - -void -ghb_presets_load(signal_user_data_t *ud) -{ - gboolean store = FALSE; - presetsPlistFile = read_config_file("presets"); - if ((presetsPlistFile == NULL) || - (ghb_value_type(presetsPlistFile) == GHB_DICT) || - (check_old_presets(presetsPlistFile))) - { - presetsPlistFile = ghb_resource_get("standard-presets"); - store = TRUE; - } - else - { - update_standard_presets(ud, presetsPlistFile); - } - presetsPlist = ghb_value_dup(presetsPlistFile); - import_xlat_presets(presetsPlist); - if (store) - store_presets(); - -} - -static void -settings_save(signal_user_data_t *ud, const GhbValue *path) -{ - GhbValue *dict; - gint *indices, len, count; - const gchar *name; - gboolean replace = FALSE; - - g_debug("settings_save"); - GhbValue *internalPlist = ghb_resource_get("internal-defaults"); - if (internalPlist == NULL) return; - count = ghb_array_len(path); - name = ghb_value_get_string(ghb_array_get(path, count-1)); - indices = ghb_preset_indices_from_path(presetsPlist, path, &len); - if (indices) - { - if (ghb_presets_get_folder(presetsPlist, indices, len)) - { - GtkWindow *hb_window; - gchar *message; - hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window")); - message = g_strdup_printf( - _("%s: Folder already exists.\n" - "You can not replace it with a preset."), - name); - ghb_message_dialog(hb_window, GTK_MESSAGE_ERROR, - message, _("Cancel"), NULL); - g_free(message); - return; - } - dict = ghb_value_dup(ud->settings); - ghb_presets_replace(presetsPlist, dict, indices, len); - replace = TRUE; - } - else - { - indices = presets_find_pos(path, PRESETS_CUSTOM, &len); - if (indices) - { - dict = ghb_value_dup(ud->settings); - ghb_presets_insert(presetsPlist, dict, indices, len); } else { - g_warning("failed to find insert path"); - return; + replace = TRUE; } } - current_preset = dict; - ghb_dict_set_int(dict, "Type", PRESETS_CUSTOM); - - ghb_dict_set(dict, "PresetName", ghb_string_value_new(name)); + dict = settings_to_preset(ud->settings); + ghb_dict_set_string(dict, "PresetName", name); if (replace) { - gint *def_indices, def_len; - def_indices = presets_find_default(presetsPlist, &def_len); - if (def_indices != NULL && - preset_path_cmp(indices, len, def_indices, def_len) != 0) + // Already exists, update its description + if (hb_preset_set(path, dict) >= 0) { - ghb_dict_set(dict, "Default", ghb_bool_value_new(FALSE)); + presets_list_update_item(ud, path, FALSE); } - presets_list_update_item(ud, indices, len, FALSE); - g_free(def_indices); } else { - ghb_dict_set(dict, "Default", ghb_bool_value_new(FALSE)); - presets_list_insert(ud, indices, len); - } - if (!ghb_dict_get_bool(ud->settings, "PictureWidthEnable")) - { - ghb_dict_remove(dict, "PictureWidth"); - } - if (!ghb_dict_get_bool(ud->settings, "PictureHeightEnable")) - { - ghb_dict_remove(dict, "PictureHeight"); + // Append to the folder list the source came from + int index = hb_preset_append(path, dict); + if (index >= 0) + { + path->index[path->depth++] = index; + presets_list_append(ud, path); + } } - ghb_dict_set(dict, "autoscale", - ghb_bool_value_new( - !ghb_dict_get_bool(ud->settings, "PictureWidthEnable") && - !ghb_dict_get_bool(ud->settings, "PictureHeightEnable") - ) - ); - + ghb_value_free(&dict); store_presets(); ud->dont_clear_presets = TRUE; // Make the new preset the selected item - ghb_select_preset2(ud->builder, indices, len); - g_free(indices); + select_preset2(ud->builder, path); ud->dont_clear_presets = FALSE; return; } static void -folder_save(signal_user_data_t *ud, const GhbValue *path) +folder_save(signal_user_data_t *ud, hb_preset_index_t *path, const char *name) { - GhbValue *dict, *folder; - gint *indices, len, count; - const gchar *name; - - count = ghb_array_len(path); - name = ghb_value_get_string(ghb_array_get(path, count-1)); - indices = ghb_preset_indices_from_path(presetsPlist, path, &len); - if (indices) + GhbValue *dict; + + dict = hb_preset_get(path); + if (dict != NULL) { - if (!ghb_presets_get_folder(presetsPlist, indices, len)) + gboolean is_folder; + int type; + const char *s; + + is_folder = ghb_dict_get_bool(dict, "Folder"); + type = ghb_dict_get_int(dict, "Type"); + s = ghb_dict_get_string(dict, "PresetName"); + if (s == NULL || strcmp(s, name) || type != PRESETS_CUSTOM || !is_folder) { - GtkWindow *hb_window; - gchar *message; - hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window")); - message = g_strdup_printf( - _("%s: Preset already exists.\n" - "You can not replace it with a folder."), - name); - ghb_message_dialog(hb_window, GTK_MESSAGE_ERROR, - message, _("Cancel"), NULL); - g_free(message); - g_free(indices); - return; + // Name changed or original preset was builtin or original + // was a not a folder. Don't replace it. + dict = NULL; + path->depth--; + if (type != PRESETS_CUSTOM) + { + // Don't put new custom presets in a builtin folder + path->depth = 1; + } } + } + if (dict != NULL) + { // Already exists, update its description - dict = presets_get_dict(presetsPlist, indices, len); + dict = hb_preset_get(path); ghb_dict_set(dict, "PresetDescription", - ghb_value_dup(ghb_dict_get( - ud->settings, "PresetDescription"))); - presets_list_update_item(ud, indices, len, FALSE); - g_free(indices); - store_presets(); - return; + ghb_value_dup(ghb_dict_get(ud->settings, "PresetDescription"))); + presets_list_update_item(ud, path, FALSE); } else { - indices = presets_find_pos(path, PRESETS_CUSTOM, &len); - if (indices) - { - dict = ghb_dict_new(); - ghb_presets_insert(presetsPlist, dict, indices, len); - } - else + dict = ghb_dict_new(); + ghb_dict_set(dict, "PresetDescription", + ghb_value_dup(ghb_dict_get(ud->settings, "PresetDescription"))); + ghb_dict_set_string(dict, "PresetName", name); + ghb_dict_set(dict, "ChildrenArray", ghb_array_new()); + ghb_dict_set_int(dict, "Type", PRESETS_CUSTOM); + ghb_dict_set_bool(dict, "Folder", TRUE); + int index = hb_preset_append(path, dict); + if (index >= 0) { - g_warning("failed to find insert path"); - return; + path->index[path->depth++] = index; + presets_list_append(ud, path); } + ghb_value_free(&dict); } - ghb_dict_set(dict, "PresetDescription", - ghb_value_dup(ghb_dict_get( - ud->settings, "PresetDescription"))); - ghb_dict_set(dict, "PresetName", ghb_string_value_new(name)); - folder = ghb_array_new(); - ghb_dict_set(dict, "ChildrenArray", folder); - ghb_dict_set(dict, "Type", ghb_int_value_new(PRESETS_CUSTOM)); - ghb_dict_set(dict, "Folder", ghb_bool_value_new(TRUE)); - - presets_list_insert(ud, indices, len); - g_free(indices); store_presets(); - return; -} - -void -ghb_presets_list_show_default(signal_user_data_t *ud) -{ - GtkTreeView *treeview; - GtkTreePath *treepath; - GtkTreeIter iter; - GtkTreeStore *store; - gint *indices, len; - - g_debug("ghb_presets_list_show_default()"); - treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); - store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); - indices = presets_find_default(presetsPlist, &len); - if (indices == NULL) return; - treepath = ghb_tree_path_new_from_indices(indices, len); - if (treepath) - { - if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath)) - { - gtk_tree_store_set(store, &iter, - 1, 800, - 2, 2 , - -1); - } - gtk_tree_path_free(treepath); - } - g_free(indices); -} - -void -ghb_presets_list_clear_default(signal_user_data_t *ud) -{ - GtkTreeView *treeview; - GtkTreePath *treepath; - GtkTreeIter iter; - GtkTreeStore *store; - gint *indices, len; - - g_debug("ghb_presets_list_clear_default ()"); - treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); - store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); - indices = presets_find_default(presetsPlist, &len); - if (indices == NULL) return; - treepath = ghb_tree_path_new_from_indices(indices, len); - if (treepath) - { - if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath)) - { - gtk_tree_store_set(store, &iter, - 1, 400, - 2, 0 , - -1); - } - gtk_tree_path_free(treepath); - } - g_free(indices); -} -static void -update_subtitle_presets(signal_user_data_t *ud) -{ - g_debug("update_subtitle_presets"); - const GhbValue *subtitle_list, *subtitle; - GhbValue *slist, *dict; - gint count, ii, source; - - subtitle_list = ghb_dict_get_value(ud->settings, "subtitle_list"); - slist = ghb_array_new(); - count = ghb_array_len(subtitle_list); - for (ii = 0; ii < count; ii++) - { - subtitle = ghb_array_get(subtitle_list, ii); - source = ghb_dict_get_int(subtitle, "SubtitleSource"); - if (source != SRTSUB) - { - dict = ghb_value_dup(subtitle); - ghb_array_append(slist, dict); - } - } - ghb_dict_set(ud->settings, "SubtitleList", slist); + return; } G_MODULE_EXPORT void preset_import_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { - GtkWidget *dialog; - GtkResponseType response; - const gchar *exportDir; - gchar *filename; - GtkFileFilter *filter; + GtkWindow *hb_window; + GtkWidget *dialog; + GtkResponseType response; + const gchar *exportDir; + gchar *filename; + GtkFileFilter *filter; - g_debug("preset_import_clicked_cb ()"); - - dialog = gtk_file_chooser_dialog_new("Import Preset", NULL, + hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window")); + dialog = gtk_file_chooser_dialog_new("Import Preset", hb_window, GTK_FILE_CHOOSER_ACTION_OPEN, GHB_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GHB_STOCK_OPEN, GTK_RESPONSE_ACCEPT, @@ -3354,11 +1666,16 @@ preset_import_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); filter = gtk_file_filter_new(); - gtk_file_filter_set_name(filter, _("Presets (*.plist)")); - gtk_file_filter_add_pattern(filter, "*.plist"); + gtk_file_filter_set_name(filter, _("Presets (*.json)")); + gtk_file_filter_add_pattern(filter, "*.json"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); + filter = gtk_file_filter_new(); + gtk_file_filter_set_name(filter, _("Legacy Presets (*.plist)")); + gtk_file_filter_add_pattern(filter, "*.plist"); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); + exportDir = ghb_dict_get_string(ud->prefs, "ExportDirectory"); if (exportDir == NULL || exportDir[0] == '\0') { @@ -3370,62 +1687,18 @@ preset_import_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) gtk_widget_hide(dialog); if (response == GTK_RESPONSE_ACCEPT) { - GhbValue *dict, *array; - gchar *dir; - gint count, ii; + gchar *dir; + int index; filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - - // import the preset if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { gtk_widget_destroy(dialog); g_free(filename); return; } - array = ghb_read_settings_file(filename); - - import_xlat_presets(array); - presets_clear_default(array); - presets_customize(array); - - count = ghb_array_len(array); - for (ii = 0; ii < count; ii++) - { - GhbValue *path, *name; - gint *indices, len; - gint index = 1; - - dict = ghb_array_get(array, ii); - path = ghb_array_new(); - name = ghb_value_dup(ghb_dict_get(dict, "PresetName")); - ghb_array_append(path, name); - indices = ghb_preset_indices_from_path(presetsPlist, path, &len); - // Modify the preset name till we make it unique - while (indices != NULL) - { - const gchar *tmp = ghb_value_get_string(name); - - ghb_value_free(&path); - g_free(indices); - - char *str = g_strdup_printf("%s %d", tmp, index); - path = ghb_array_new(); - name = ghb_string_value_new(str); - ghb_array_append(path, name); - g_free(str); - - index++; - indices = ghb_preset_indices_from_path(presetsPlist, path, &len); - } - ghb_dict_set(dict, "PresetName", ghb_value_dup(name)); - indices = presets_find_pos(path, PRESETS_CUSTOM, &len); - ghb_presets_insert(presetsPlist, ghb_value_dup(dict), indices, len); - presets_list_insert(ud, indices, len); - ghb_value_free(&path); - g_free(indices); - } - ghb_value_free(&array); + // import the preset + index = hb_presets_add_path(filename); exportDir = ghb_dict_get_string(ud->prefs, "ExportDirectory"); dir = g_path_get_dirname(filename); @@ -3437,32 +1710,37 @@ preset_import_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) g_free(filename); g_free(dir); store_presets(); + + // Re-init the UI preset list + ghb_presets_list_reinit(ud); + if (index < 0) + { + ghb_select_default_preset(ud->builder); + } + else + { + hb_preset_index_t path; + path.index[0] = index; + path.depth = 1; + select_preset2(ud->builder, &path); + } } gtk_widget_destroy(dialog); } -GhbValue* +hb_preset_index_t * get_selected_path(signal_user_data_t *ud) { - GtkTreeView *treeview; + GtkTreeView *treeview; GtkTreeSelection *selection; - GtkTreeModel *store; - GtkTreeIter iter; + GtkTreeModel *store; + GtkTreeIter iter; - treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + 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)) { - GtkTreePath *treepath; - gint *indices, len; - GhbValue *path; - - treepath = gtk_tree_model_get_path(store, &iter); - indices = gtk_tree_path_get_indices(treepath); - len = gtk_tree_path_get_depth(treepath); - - path = preset_path_from_indices(presetsPlist, indices, len); - return path; + return ghb_tree_get_index(store, &iter); } return NULL; } @@ -3470,29 +1748,31 @@ get_selected_path(signal_user_data_t *ud) G_MODULE_EXPORT void preset_export_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { - GtkWidget *dialog; - GtkResponseType response; - GhbValue *preset; - const gchar *name = ""; - gint count, *indices, len; - const gchar *exportDir; - gchar *filename; - - g_debug("preset_export_clicked_cb ()"); - preset = get_selected_path(ud); - if (preset == NULL) - return; + hb_preset_index_t *path; + const gchar *name; + GtkWindow *hb_window; + GtkWidget *dialog; + GtkResponseType response; + const gchar *exportDir; + gchar *filename; - count = ghb_array_len(preset); - if (count <= 0) + path = get_selected_path(ud); + if (path == NULL || path->depth <= 0) { - ghb_value_free(&preset); + free(path); return; } - name = ghb_value_get_string(ghb_array_get(preset, count-1)); + GhbValue *dict = hb_preset_get(path); + free(path); + if (dict == NULL) + { + return; + } + name = ghb_dict_get_string(dict, "PresetName"); - dialog = gtk_file_chooser_dialog_new(_("Export Preset"), NULL, + hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window")); + dialog = gtk_file_chooser_dialog_new(_("Export Preset"), hb_window, GTK_FILE_CHOOSER_ACTION_SAVE, GHB_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GHB_STOCK_SAVE, GTK_RESPONSE_ACCEPT, @@ -3508,30 +1788,16 @@ preset_export_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename); g_free(filename); - indices = ghb_preset_indices_from_path(presetsPlist, preset, &len); - if (indices == NULL) - { - ghb_value_free(&preset); - return; - } - response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_hide(dialog); if (response == GTK_RESPONSE_ACCEPT) { - GhbValue *export, *dict; - gchar *dir; + gchar *dir; filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); // export the preset - dict = presets_get_dict(presetsPlist, indices, len); - - export = ghb_value_dup(dict); - export_xlat_presets(export); - hb_preset_write_json(export, filename); - ghb_value_free(&export); - + hb_presets_write_json(dict, filename); exportDir = ghb_dict_get_string(ud->prefs, "ExportDirectory"); dir = g_path_get_dirname(filename); if (strcmp(dir, exportDir) != 0) @@ -3543,42 +1809,27 @@ preset_export_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) g_free(filename); } gtk_widget_destroy(dialog); - g_free(indices); - ghb_value_free(&preset); } G_MODULE_EXPORT void presets_new_folder_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { - GtkWidget *dialog; - GtkEntry *entry; - GtkTextView *desc; - GtkResponseType response; - GhbValue *preset, *dict; - const gchar *name = ""; - const gchar *description = ""; - gint count, *indices, len; - - g_debug("presets_new_folder_clicked_cb ()"); - preset = get_selected_path(ud); - count = ghb_array_len(preset); - if (count > 0) - name = ghb_value_get_string(ghb_array_get(preset, count-1)); - else - count = 1; + GtkWidget *dialog; + GtkEntry *entry; + GtkTextView *desc; + GtkResponseType response; + hb_preset_index_t *path; + const gchar *name; + const gchar *description; - indices = ghb_preset_indices_from_path(presetsPlist, preset, &len); - dict = presets_get_dict(presetsPlist, indices, len); - if (dict != NULL) - { - description = ghb_value_get_string( - ghb_dict_get(dict, "PresetDescription")); - ghb_ui_update(ud, "FolderDescription", ghb_string_value(description)); - } + path = get_selected_path(ud); + name = ghb_dict_get_string(ud->settings, "PresetName"); + description = ghb_dict_get_string(ud->settings, "PresetDescription"); + ghb_ui_update(ud, "FolderDescription", ghb_string_value(description)); - desc = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "FolderDescription")); + desc = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "FolderDescription")); dialog = GHB_WIDGET(ud->builder, "preset_new_folder_dialog"); - entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "FolderName")); + entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "FolderName")); gtk_entry_set_text(entry, name); response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_hide(dialog); @@ -3586,60 +1837,37 @@ presets_new_folder_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { // save the preset const gchar *name = gtk_entry_get_text(entry); - GhbValue *dest; - - if (count > MAX_NESTED_PRESET-1) - count = MAX_NESTED_PRESET-1; - - dest = ghb_array_new(); - if (indices != NULL) - { - gint ptype; - - ptype = ghb_presets_get_type(presetsPlist, indices, len); - if (ptype == PRESETS_CUSTOM) - { - ghb_array_copy(dest, preset, count-1); - } - } - ghb_array_append(dest, ghb_string_value_new(name)); - GhbValue *val = ghb_widget_value(GTK_WIDGET(desc)); + GhbValue *val = ghb_widget_value(GTK_WIDGET(desc)); ghb_dict_set(ud->settings, "PresetDescription", ghb_value_dup(val)); - folder_save(ud, dest); - ghb_value_free(&dest); + folder_save(ud, path, name); } - g_free(indices); - ghb_value_free(&preset); + free(path); } G_MODULE_EXPORT void presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { - GtkWidget *dialog; - GtkEntry *entry; - GtkTextView *desc; - GtkResponseType response; - GhbValue *preset; - const gchar *name = ""; - gint count, *indices, len; - - g_debug("presets_save_clicked_cb ()"); - preset = get_selected_path(ud); - if (preset == NULL) - preset = ghb_value_dup(ghb_dict_get_value(ud->settings, "preset")); - - count = ghb_array_len(preset); - if (count > 0) - name = ghb_value_get_string(ghb_array_get(preset, count-1)); - else - count = 1; + const gchar *name; + const gchar *fullname; + hb_preset_index_t *path; + int width, height; + gboolean autoscale; + GtkWidget *dialog; + GtkEntry *entry; + GtkTextView *desc; + GtkResponseType response; + + name = ghb_dict_get_string(ud->settings, "PresetName"); + fullname = ghb_dict_get_string(ud->settings, "PresetFullName"); + width = ghb_dict_get_int(ud->settings, "PictureWidth"); + height = ghb_dict_get_int(ud->settings, "PictureHeight"); + autoscale = ghb_dict_get_bool(ud->settings, "autoscale"); - desc = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "PresetDescription")); - int width = ghb_dict_get_int(ud->settings, "PictureWidth"); - int height = ghb_dict_get_int(ud->settings, "PictureHeight"); - gboolean autoscale = ghb_dict_get_bool(ud->settings, "autoscale"); ghb_ui_update(ud, "PictureWidthEnable", ghb_boolean_value(!autoscale)); ghb_ui_update(ud, "PictureHeightEnable", ghb_boolean_value(!autoscale)); + + path = hb_preset_search_index(fullname, 0); + desc = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "PresetDescription")); if (!width) { width = ghb_dict_get_int(ud->settings, "scale_width"); @@ -3650,39 +1878,20 @@ presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) height = ghb_dict_get_int(ud->settings, "scale_height"); ghb_ui_update(ud, "PictureHeight", ghb_int_value(height)); } - dialog = GHB_WIDGET(ud->builder, "preset_save_dialog"); - entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "PresetName")); + + dialog = GHB_WIDGET(ud->builder, "preset_save_dialog"); + entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "PresetName")); gtk_entry_set_text(entry, name); 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); - GhbValue *dest; - - dest = ghb_array_new(); - indices = ghb_preset_indices_from_path(presetsPlist, preset, &len); - if (indices) - { - gint ptype; - - ptype = ghb_presets_get_type(presetsPlist, indices, len); - if (ptype == PRESETS_CUSTOM) - { - ghb_array_copy(dest, preset, count-1); - } - g_free(indices); - } - ghb_array_append(dest, ghb_string_value_new(name)); - + name = gtk_entry_get_text(entry); ghb_widget_to_setting(ud->settings, GTK_WIDGET(desc)); - - update_subtitle_presets(ud); - settings_save(ud, dest); - ghb_value_free(&dest); + settings_save(ud, path, name); } - ghb_value_free(&preset); + free(path); } G_MODULE_EXPORT void @@ -3694,86 +1903,83 @@ preset_type_changed_cb(GtkWidget *widget, signal_user_data_t *ud) G_MODULE_EXPORT void presets_restore_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { - GhbValue *preset; - - g_debug("presets_restore_clicked_cb ()"); - // Reload only the standard presets - ghb_presets_reload(ud); - // Updating the presets list shuffles things around - // need to make sure the proper preset is selected - preset = ghb_dict_get_value(ud->settings, "preset"); - ghb_select_preset(ud->builder, preset); + // Reload the builtin presets + hb_presets_builtin_update(); + store_presets(); + + ghb_presets_list_reinit(ud); + ghb_select_default_preset(ud->builder); } G_MODULE_EXPORT void presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { - GtkTreeView *treeview; + GtkTreeView *treeview; GtkTreeSelection *selection; - GtkTreeModel *store; - GtkTreeIter iter; - gchar *preset; - GtkResponseType response; + GtkTreeModel *store; + GtkTreeIter iter; + gchar *preset; + GtkResponseType response; - g_debug("presets_remove_clicked_cb ()"); - treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + 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)) { - GtkWindow *hb_window; - GtkWidget *dialog; - GtkTreePath *path; - gint *indices, len; - gboolean folder; + GtkWindow *hb_window; + GtkWidget *dialog; + gboolean is_folder; + hb_preset_index_t *path; gtk_tree_model_get(store, &iter, 0, &preset, -1); - path = gtk_tree_model_get_path(store, &iter); - indices = gtk_tree_path_get_indices(path); - len = gtk_tree_path_get_depth(path); - folder = ghb_presets_get_folder(presetsPlist, indices, len); + path = ghb_tree_get_index(store, &iter); + is_folder = preset_is_folder(path); hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window")); dialog = gtk_message_dialog_new(hb_window, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Confirm deletion of %s:\n\n%s"), - folder ? _("folder") : _("preset"), + is_folder ? _("folder") : _("preset"), preset); response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy (dialog); if (response == GTK_RESPONSE_YES) { GtkTreeIter nextIter = iter; - gboolean valid = TRUE; + gboolean valid = TRUE; + + // Determine which preset to highlight after deletion done if (!gtk_tree_model_iter_next(store, &nextIter)) { - if (!gtk_tree_model_iter_parent(store, &nextIter, &iter)) + nextIter = iter; + if (!gtk_tree_model_iter_previous(store, &nextIter)) { - valid = FALSE; + nextIter = iter; + if (!gtk_tree_model_iter_parent(store, &nextIter, &iter)) + { + nextIter = iter; + valid = gtk_tree_model_get_iter_first(store, &nextIter); + } } } + // Remove the selected item // First unselect it so that selecting the new item works properly - gtk_tree_selection_unselect_iter (selection, &iter); - if (ghb_presets_remove(presetsPlist, indices, len)) + gtk_tree_selection_unselect_iter(selection, &iter); + if (hb_preset_delete(path) >= 0) { store_presets(); - presets_list_remove(ud, indices, len); + presets_list_remove(ud, path); } - if (!valid) - valid = gtk_tree_model_get_iter_first(store, &nextIter); if (valid) { - GtkTreePath *path; - gint *indices; + hb_preset_index_t *path; - path = gtk_tree_model_get_path(store, &nextIter); - indices = gtk_tree_path_get_indices(path); - len = gtk_tree_path_get_depth(path); - ghb_select_preset2(ud->builder, indices, len); - gtk_tree_path_free(path); + path = ghb_tree_get_index(store, &nextIter); + select_preset2(ud->builder, path); + free(path); } } - gtk_tree_path_free(path); + free(path); g_free(preset); } } @@ -3781,52 +1987,55 @@ presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) // controls where valid drop locations are G_MODULE_EXPORT gboolean presets_drag_motion_cb( - GtkTreeView *tv, - GdkDragContext *ctx, - gint x, - gint y, - guint time, + GtkTreeView *tv, + GdkDragContext *ctx, + gint x, + gint y, + guint time, signal_user_data_t *ud) { - GtkTreePath *path = NULL; - GtkTreeViewDropPosition drop_pos; - gint *indices, len; - GtkTreeIter iter; - GtkTreeView *srctv; - GtkTreeModel *model; - GtkTreeSelection *select; - gint src_ptype, dst_ptype; - gboolean src_folder, dst_folder; - GhbValue *preset; - gint tree_depth, ii; - GtkWidget *widget; + GtkTreeViewDropPosition drop_pos; + GtkTreeIter iter; + GtkTreeView *srctv; + GtkTreeModel *model; + GtkTreeSelection *select; + GtkTreePath *treepath; + hb_preset_index_t *path; + gint src_ptype, dst_ptype; + gboolean src_folder, dst_folder; + GhbValue *src_preset, *dst_preset; + gint tree_depth, ii; + GtkWidget *widget; widget = gtk_drag_get_source_widget(ctx); if (widget == NULL || widget != GTK_WIDGET(tv)) return TRUE; // Get the type of the object being dragged - srctv = GTK_TREE_VIEW(gtk_drag_get_source_widget(ctx)); - select = gtk_tree_view_get_selection (srctv); + srctv = GTK_TREE_VIEW(gtk_drag_get_source_widget(ctx)); + select = gtk_tree_view_get_selection(srctv); gtk_tree_selection_get_selected (select, &model, &iter); - path = gtk_tree_model_get_path (model, &iter); - indices = gtk_tree_path_get_indices(path); - len = gtk_tree_path_get_depth(path); + path = ghb_tree_get_index(model, &iter); - preset = presets_get_dict(presetsPlist, indices, len); - tree_depth = preset_tree_depth(preset); + src_preset = hb_preset_get(path); + free(path); + if (src_preset == NULL) + { + gdk_drag_status(ctx, 0, time); + return TRUE; + } - src_ptype = ghb_presets_get_type(presetsPlist, indices, len); - src_folder = ghb_presets_get_folder(presetsPlist, indices, len); - gtk_tree_path_free(path); + tree_depth = preset_tree_depth(src_preset); + src_ptype = ghb_dict_get_int(src_preset, "Type"); + src_folder = ghb_dict_get_bool(src_preset, "Folder"); if (src_folder && tree_depth == 1) tree_depth = 2; // The rest checks that the destination is a valid position // in the list. - gtk_tree_view_get_dest_row_at_pos (tv, x, y, &path, &drop_pos); - if (path == NULL) + gtk_tree_view_get_dest_row_at_pos(tv, x, y, &treepath, &drop_pos); + if (treepath == NULL) { gdk_drag_status(ctx, 0, time); return TRUE; @@ -3838,7 +2047,7 @@ presets_drag_motion_cb( return TRUE; } - len = gtk_tree_path_get_depth(path); + int len = gtk_tree_path_get_depth(treepath); if (len+tree_depth-1 >= MAX_NESTED_PRESET) { if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) @@ -3847,11 +2056,21 @@ presets_drag_motion_cb( drop_pos = GTK_TREE_VIEW_DROP_AFTER; } for (ii = len+tree_depth-1; ii > MAX_NESTED_PRESET; ii--) - gtk_tree_path_up(path); - indices = gtk_tree_path_get_indices(path); - len = gtk_tree_path_get_depth(path); - dst_ptype = ghb_presets_get_type(presetsPlist, indices, len); - dst_folder = ghb_presets_get_folder(presetsPlist, indices, len); + gtk_tree_path_up(treepath); + path = ghb_tree_path_get_index(treepath); + + dst_preset = hb_preset_get(path); + free(path); + if (dst_preset != NULL) + { + dst_ptype = ghb_dict_get_int(dst_preset, "Type"); + dst_folder = ghb_dict_get_bool(dst_preset, "Folder"); + } + else + { + dst_ptype = PRESETS_CUSTOM; + dst_folder = FALSE; + } // Don't allow mixing custom presets in the builtins if (dst_ptype != PRESETS_CUSTOM) @@ -3869,179 +2088,188 @@ presets_drag_motion_cb( drop_pos = GTK_TREE_VIEW_DROP_AFTER; } - len = gtk_tree_path_get_depth(path); - gtk_tree_view_set_drag_dest_row(tv, path, drop_pos); - gtk_tree_path_free(path); + len = gtk_tree_path_get_depth(treepath); + gtk_tree_view_set_drag_dest_row(tv, treepath, drop_pos); + gtk_tree_path_free(treepath); gdk_drag_status(ctx, GDK_ACTION_MOVE, time); return TRUE; } G_MODULE_EXPORT void presets_drag_cb( - GtkTreeView *dstwidget, - GdkDragContext *dc, - gint x, gint y, - GtkSelectionData *selection_data, - guint info, guint t, + GtkTreeView *dst_widget, + GdkDragContext *dc, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint t, signal_user_data_t *ud) { - GtkTreePath *path = NULL; - GtkTreeViewDropPosition drop_pos; - GtkTreeIter dstiter, srciter; - gint *dst_indices, dst_len, *src_indices, src_len; - gint src_ptype; - gboolean src_folder, dst_folder; + GtkTreePath *dst_treepath = NULL; + GtkTreeViewDropPosition drop_pos; + GtkTreeIter dst_iter, src_iter; + gint src_ptype; + gboolean src_folder, dst_folder; - GtkTreeModel *dstmodel = gtk_tree_view_get_model(dstwidget); + GtkTreeModel *dst_model = gtk_tree_view_get_model(dst_widget); - g_debug("preset_drag_cb ()"); // This doesn't work here for some reason... // gtk_tree_view_get_drag_dest_row(dstwidget, &path, &drop_pos); - gtk_tree_view_get_dest_row_at_pos (dstwidget, x, y, &path, &drop_pos); + gtk_tree_view_get_dest_row_at_pos(dst_widget, x, y, + &dst_treepath, &drop_pos); // This little hack is needed because attempting to drop after - // the last item gives us no path or drop_pos. - if (path == NULL) + // the last item gives us no dst_treepath or drop_pos. + if (dst_treepath == NULL) { gint n_children; - n_children = gtk_tree_model_iter_n_children(dstmodel, NULL); + n_children = gtk_tree_model_iter_n_children(dst_model, NULL); if (n_children) { drop_pos = GTK_TREE_VIEW_DROP_AFTER; - path = gtk_tree_path_new_from_indices(n_children-1, -1); + dst_treepath = gtk_tree_path_new_from_indices(n_children-1, -1); } else { drop_pos = GTK_TREE_VIEW_DROP_BEFORE; - path = gtk_tree_path_new_from_indices(0, -1); + dst_treepath = gtk_tree_path_new_from_indices(0, -1); } } - if (path) + if (dst_treepath) { - GtkTreeView *srcwidget; - GtkTreeModel *srcmodel; - GtkTreeSelection *select; - GtkTreePath *srcpath = NULL; - GhbValue *preset; - gint tree_depth, ii; - - srcwidget = GTK_TREE_VIEW(gtk_drag_get_source_widget(dc)); - select = gtk_tree_view_get_selection (srcwidget); - gtk_tree_selection_get_selected (select, &srcmodel, &srciter); - - srcpath = gtk_tree_model_get_path (srcmodel, &srciter); - src_indices = gtk_tree_path_get_indices(srcpath); - src_len = gtk_tree_path_get_depth(srcpath); - src_ptype = ghb_presets_get_type(presetsPlist, src_indices, src_len); - src_folder = ghb_presets_get_folder(presetsPlist, src_indices, src_len); - preset = ghb_value_dup( - presets_get_dict(presetsPlist, src_indices, src_len)); - gtk_tree_path_free(srcpath); + GtkTreeView *src_widget; + GtkTreeModel *src_model; + GtkTreeSelection *select; + gint tree_depth, ii; + hb_preset_index_t *dst_path, *src_path; + hb_value_t *src_preset; + + src_widget = GTK_TREE_VIEW(gtk_drag_get_source_widget(dc)); + select = gtk_tree_view_get_selection (src_widget); + gtk_tree_selection_get_selected(select, &src_model, &src_iter); + + src_path = ghb_tree_get_index(src_model, &src_iter); + src_ptype = preset_get_type(src_path); + src_folder = preset_is_folder(src_path); // Don't allow repositioning of builtin presets if (src_ptype != PRESETS_CUSTOM) + { + free(src_path); return; + } - tree_depth = preset_tree_depth(preset); + src_preset = hb_preset_get(src_path); + tree_depth = preset_tree_depth(src_preset); if (src_folder && tree_depth == 1) tree_depth = 2; - dst_len = gtk_tree_path_get_depth(path); - if (dst_len+tree_depth-1 >= MAX_NESTED_PRESET) + dst_path = ghb_tree_path_get_index(dst_treepath); + if (dst_path->depth + tree_depth - 1 >= MAX_NESTED_PRESET) { if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) drop_pos = GTK_TREE_VIEW_DROP_BEFORE; - if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) + else if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) drop_pos = GTK_TREE_VIEW_DROP_AFTER; } - for (ii = dst_len+tree_depth-1; ii > MAX_NESTED_PRESET; ii--) - gtk_tree_path_up(path); - dst_indices = gtk_tree_path_get_indices(path); - dst_len = gtk_tree_path_get_depth(path); - dst_folder = ghb_presets_get_folder(presetsPlist, dst_indices, dst_len); + for (ii = dst_path->depth + tree_depth-1; ii > MAX_NESTED_PRESET; ii--) + { + gtk_tree_path_up(dst_treepath); + dst_path->depth--; + } + + dst_folder = preset_is_folder(dst_path); // Only allow *drop into* for folders if (!dst_folder) { if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) drop_pos = GTK_TREE_VIEW_DROP_BEFORE; - if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) + else if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) drop_pos = GTK_TREE_VIEW_DROP_AFTER; } - if (gtk_tree_model_get_iter (dstmodel, &dstiter, path)) + free(dst_path); + if (gtk_tree_model_get_iter(dst_model, &dst_iter, dst_treepath)) { GtkTreeIter iter; - GtkTreePath *dstpath = NULL; + // Insert new empty row in UI preset list + // This logic determines the final position of the preset, + // i.e. before, after or inside the target entry. + // So the dst_path to move the preset to must be computed + // after moving the entry in the UI list switch (drop_pos) { case GTK_TREE_VIEW_DROP_BEFORE: - gtk_tree_store_insert_before(GTK_TREE_STORE (dstmodel), - &iter, NULL, &dstiter); + gtk_tree_store_insert_before(GTK_TREE_STORE(dst_model), + &iter, NULL, &dst_iter); break; case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: - gtk_tree_store_insert(GTK_TREE_STORE (dstmodel), - &iter, &dstiter, 0); + gtk_tree_store_insert(GTK_TREE_STORE(dst_model), + &iter, &dst_iter, 0); break; case GTK_TREE_VIEW_DROP_AFTER: - gtk_tree_store_insert_after(GTK_TREE_STORE (dstmodel), - &iter, NULL, &dstiter); + gtk_tree_store_insert_after(GTK_TREE_STORE(dst_model), + &iter, NULL, &dst_iter); break; case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: - gtk_tree_store_insert_after(GTK_TREE_STORE (dstmodel), - &iter, &dstiter, 0); + gtk_tree_store_insert_after(GTK_TREE_STORE(dst_model), + &iter, &dst_iter, NULL); break; default: break; } - dstpath = gtk_tree_model_get_path (dstmodel, &iter); - dst_indices = gtk_tree_path_get_indices(dstpath); - dst_len = gtk_tree_path_get_depth(dstpath); - ghb_presets_insert(presetsPlist, preset, dst_indices, dst_len); - gtk_tree_path_free(dstpath); - - srcpath = gtk_tree_model_get_path (srcmodel, &srciter); - src_indices = gtk_tree_path_get_indices(srcpath); - src_len = gtk_tree_path_get_depth(srcpath); - ghb_presets_remove(presetsPlist, src_indices, src_len); - gtk_tree_path_free(srcpath); + // Move source preset at the desired location + dst_path = ghb_tree_get_index(dst_model, &iter); + hb_preset_move(src_path, dst_path); + free(dst_path); - gtk_tree_store_remove (GTK_TREE_STORE (srcmodel), &srciter); + // Remove the old entry in the UI list + gtk_tree_store_remove(GTK_TREE_STORE(src_model), &src_iter); - dstpath = gtk_tree_model_get_path (dstmodel, &iter); - dst_indices = gtk_tree_path_get_indices(dstpath); - dst_len = gtk_tree_path_get_depth(dstpath); - presets_list_update_item(ud, dst_indices, dst_len, TRUE); - gtk_tree_path_free(dstpath); + // UI elements were shuffled again. recompute dst_path + dst_path = ghb_tree_get_index(dst_model, &iter); + presets_list_update_item(ud, dst_path, TRUE); + select_preset2(ud->builder, dst_path); + free(dst_path); store_presets(); } - gtk_tree_path_free(path); + gtk_tree_path_free(dst_treepath); + free(src_path); } } void presets_row_expanded_cb( - GtkTreeView *treeview, - GtkTreeIter *iter, - GtkTreePath *path, + GtkTreeView *treeview, + GtkTreeIter *iter, + GtkTreePath *treepath, signal_user_data_t *ud) { - gint *indices, len; - gboolean expanded, folder; - GhbValue *dict; + hb_preset_index_t *path; + gboolean expanded; + GhbValue *dict; + + expanded = gtk_tree_view_row_expanded(treeview, treepath); + path = ghb_tree_path_get_index(treepath); + dict = hb_preset_get(path); + free(path); - expanded = gtk_tree_view_row_expanded(treeview, path); - indices = gtk_tree_path_get_indices(path); - len = gtk_tree_path_get_depth(path); - dict = presets_get_dict(presetsPlist, indices, len); - if (preset_folder_is_open(dict)) + // Sanity check + if (!ghb_dict_get_bool(dict, "Folder")) + { + g_warning("presets_row_expand_cb: Desync between presets and list"); + return; + } + if (ghb_dict_get_bool(dict, "FolderOpen")) { if (expanded) { @@ -4052,118 +2280,96 @@ presets_row_expanded_cb( { return; } - folder = ghb_presets_get_folder(presetsPlist, indices, len); - if (folder) - { - presets_set_folder_open(expanded, indices, len); - } - - // Collapsing parent folder collapses all children - if (!expanded) - { - GhbValue *presets = NULL; - gint *more_indices, count, ii; + ghb_dict_set_bool(dict, "FolderOpen", expanded); + store_presets(); +} - more_indices = g_malloc((len+1)*sizeof(gint)); - memcpy(more_indices, indices, len*sizeof(gint)); +char* +preset_get_fullname(hb_preset_index_t *path) +{ + int ii; + GString *gstr; + hb_preset_index_t *tmp; + GhbValue *dict; - presets = presets_get_folder(presetsPlist, indices, len); - count = ghb_array_len(presets); - for (ii = 0; ii < count; ii++) + gstr = g_string_new(""); + tmp = hb_preset_index_dup(path); + for (ii = 1; ii <= path->depth; ii++) + { + const char *name; + tmp->depth = ii; + dict = hb_preset_get(tmp); + if (dict == NULL) { - dict = ghb_array_get(presets, ii); - folder = ghb_preset_folder(dict); - if (folder) - { - more_indices[len] = ii; - presets_set_folder_open(expanded, more_indices, len+1); - } + break; + } + name = ghb_dict_get_string(dict, "PresetName"); + if (name != NULL) + { + g_string_append(gstr, "/"); + g_string_append(gstr, name); } - g_free(more_indices); } - store_presets(); + free(tmp); + char *str = g_string_free(gstr, FALSE); + return str; } +// Makes a copy of the preset and assigns "PresetFullName" which +// is use to look up the preset in the preset list should the need +// arrise, e.g. saving changes to the preset. GhbValue* ghb_get_current_preset(signal_user_data_t *ud) { - GtkTreeView *tv; - GtkTreeModel *tm; + GtkTreeView *tv; + GtkTreeModel *tm; GtkTreeSelection *ts; - GtkTreeIter ti; - GhbValue *preset = NULL; + GtkTreeIter ti; + GhbValue *preset = NULL; tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); ts = gtk_tree_view_get_selection(tv); if (gtk_tree_selection_get_selected(ts, &tm, &ti)) { - GtkTreePath *tp; - gint *indices, len; - - tp = gtk_tree_model_get_path(tm, &ti); - indices = gtk_tree_path_get_indices(tp); - len = gtk_tree_path_get_depth(tp); - preset = presets_get_dict(presetsPlist, indices, len); - gtk_tree_path_free(tp); - } - return preset; -} + hb_preset_index_t *path; -GhbValue* -ghb_get_current_preset_path(signal_user_data_t *ud) -{ - GtkTreeView *tv; - GtkTreeModel *tm; - GtkTreeSelection *ts; - GtkTreeIter ti; - GhbValue *path = NULL; + path = ghb_tree_get_index(tm, &ti); + preset = hb_preset_get(path); + if (preset != NULL) + { + char *fullname; - tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); - ts = gtk_tree_view_get_selection(tv); - if (gtk_tree_selection_get_selected(ts, &tm, &ti)) - { - GtkTreePath *tp; - gint *indices, len; - - tp = gtk_tree_model_get_path(tm, &ti); - indices = gtk_tree_path_get_indices(tp); - len = gtk_tree_path_get_depth(tp); - path = preset_path_from_indices(presetsPlist, indices, len); - gtk_tree_path_free(tp); + preset = hb_value_dup(preset); + fullname = preset_get_fullname(path); + ghb_dict_set_string(preset, "PresetFullName", fullname); + free(fullname); + } + free(path); } - return path; + return preset; } G_MODULE_EXPORT void presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud) { - GtkTreeModel *store; - GtkTreeIter iter; - GtkWidget *widget; + GtkWidget *widget; + hb_preset_index_t *path; - g_debug("presets_list_selection_changed_cb ()"); widget = GHB_WIDGET (ud->builder, "presets_remove"); - if (gtk_tree_selection_get_selected(selection, &store, &iter)) + path = get_selected_path(ud); + if (path != NULL) { - GtkTreePath *treepath; - gint *indices, len; - gboolean folder; - - treepath = gtk_tree_model_get_path(store, &iter); - indices = gtk_tree_path_get_indices(treepath); - len = gtk_tree_path_get_depth(treepath); - - folder = ghb_presets_get_folder(presetsPlist, indices, len); - if (!folder && !ghb_dict_get_bool(ud->settings, "preset_reload")) + GhbValue *dict = hb_preset_get(path); + if (!ghb_dict_get_bool(dict, "Folder") && + !ghb_dict_get_bool(ud->settings, "preset_reload")) { - ghb_set_preset_settings_from_indices(ud, indices, len); - ghb_dict_set_bool(ud->settings, "preset_modified", FALSE); + ghb_preset_to_settings(ud->settings, dict); + char *fullname = preset_get_fullname(path); + ghb_dict_set_string(ud->settings, "PresetFullName", fullname); + free(fullname); ghb_set_current_title_settings(ud); - ghb_load_settings(ud); + ghb_load_post_settings(ud); } - ghb_dict_set_bool(ud->settings, "preset_reload", FALSE); - - gtk_tree_path_free(treepath); gtk_widget_set_sensitive(widget, TRUE); } else @@ -4176,26 +2382,28 @@ presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_ void ghb_clear_presets_selection(signal_user_data_t *ud) { - GtkTreeView *treeview; + GtkTreeView *treeview; GtkTreeSelection *selection; if (ud->dont_clear_presets) return; - g_debug("ghb_clear_presets_selection()"); - treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); selection = gtk_tree_view_get_selection (treeview); gtk_tree_selection_unselect_all (selection); ghb_dict_set_bool(ud->settings, "preset_modified", TRUE); } G_MODULE_EXPORT void -presets_frame_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, signal_user_data_t *ud) +presets_frame_size_allocate_cb( + GtkWidget *widget, + GtkAllocation *allocation, + signal_user_data_t *ud) { - GtkTreeView *treeview; + GtkTreeView *treeview; GtkTreeSelection *selection; - GtkTreeModel *store; - GtkTreeIter iter; + GtkTreeModel *store; + GtkTreeIter iter; - treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); + 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)) { @@ -4210,72 +2418,53 @@ presets_frame_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, sig G_MODULE_EXPORT void presets_default_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { - GhbValue *preset; - gint *indices, len; - - g_debug("presets_default_clicked_cb ()"); - preset = get_selected_path(ud); - indices = ghb_preset_indices_from_path(presetsPlist, preset, &len); - if (indices) + hb_preset_index_t *path = get_selected_path(ud); + if (path != NULL) { - if (!ghb_presets_get_folder(presetsPlist, indices, len)) + hb_value_t *dict = hb_preset_get(path); + if (dict != NULL && !ghb_dict_get_bool(dict, "Folder")) { ghb_presets_list_clear_default(ud); - presets_set_default(indices, len); + ghb_dict_set_bool(dict, "Default", 1); ghb_presets_list_show_default(ud); + store_presets(); } - g_free(indices); + g_free(path); } - ghb_value_free(&preset); } G_MODULE_EXPORT void preset_edited_cb( GtkCellRendererText *cell, - gchar *path, - gchar *text, - signal_user_data_t *ud) + gchar *treepath_s, + gchar *text, + signal_user_data_t *ud) { - GtkTreePath *treepath; - GtkTreeStore *store; - GtkTreeView *treeview; - GtkTreeIter iter; - gint *indices, len, count; - GhbValue *dict; - GhbValue *preset, *dest; - - g_debug("preset_edited_cb ()"); - g_debug("path (%s)", path); - g_debug("text (%s)", text); - - preset = get_selected_path(ud); - dest = ghb_array_new(); - count = ghb_array_len(preset); - ghb_array_copy(dest, preset, count-1); - ghb_array_append(dest, ghb_string_value_new(text)); - indices = ghb_preset_indices_from_path(presetsPlist, dest, &len); - ghb_value_free(&dest); - if (indices != NULL) - { - // Already exists - g_free(indices); - ghb_value_free(&preset); - return; - } + GtkTreePath *treepath; + GtkTreeStore *store; + GtkTreeView *treeview; + GtkTreeIter iter; + GhbValue *dict; + hb_preset_index_t *path; treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list")); - store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); - treepath = gtk_tree_path_new_from_string (path); - indices = gtk_tree_path_get_indices(treepath); - len = gtk_tree_path_get_depth(treepath); - gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath); - gtk_tree_store_set(store, &iter, 0, text, -1); + store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); + treepath = gtk_tree_path_new_from_string(treepath_s); + path = ghb_tree_path_get_index(treepath); + if (path != NULL) + { + dict = hb_preset_get(path); + if (dict != NULL) + { + gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath); + gtk_tree_store_set(store, &iter, 0, text, -1); - dict = presets_get_dict(presetsPlist, indices, len); - ghb_dict_set(dict, "PresetName", ghb_string_value_new(text)); - store_presets(); - gtk_tree_path_free (treepath); - ghb_value_free(&preset); + ghb_dict_set_string(dict, "PresetName", text); + store_presets(); + } + } + gtk_tree_path_free(treepath); + free(path); } G_MODULE_EXPORT void diff --git a/gtk/src/presets.h b/gtk/src/presets.h index d9fe4e92f..791900541 100644 --- a/gtk/src/presets.h +++ b/gtk/src/presets.h @@ -16,43 +16,32 @@ #if !defined(_GHB_PRESETS_H_) #define _GHB_PRESETS_H_ +#include "hb.h" #include "values.h" -void ghb_settings_save(signal_user_data_t *ud, const gchar *name); void ghb_presets_load(signal_user_data_t *ud); void ghb_update_from_preset(signal_user_data_t *ud, const gchar *key); void ghb_settings_init(GhbValue *settings, const char *name); void ghb_settings_close(); -void ghb_globals_to_ui(signal_user_data_t *ud); void ghb_prefs_load(signal_user_data_t *ud); -void ghb_prefs_to_ui(signal_user_data_t *ud); -void ghb_prefs_save(GhbValue *settings); void ghb_pref_save(GhbValue *settings, const gchar *key); void ghb_pref_set(GhbValue *settings, const gchar *key); void ghb_prefs_store(void); void ghb_save_queue(GhbValue *queue); -GhbValue* ghb_load_queue(); GhbValue* ghb_load_old_queue(int pid); -void ghb_remove_queue_file(void); void ghb_remove_old_queue_file(int pid); gchar* ghb_get_user_config_dir(gchar *subdir); void ghb_settings_to_ui(signal_user_data_t *ud, GhbValue *dict); void ghb_clear_presets_selection(signal_user_data_t *ud); -void ghb_select_preset(GtkBuilder *builder, const GhbValue *preset); +void ghb_select_preset(GtkBuilder *builder, const char *name); void ghb_select_default_preset(GtkBuilder *builder); -void ghb_presets_list_init(signal_user_data_t *ud, gint *indices, gint len); -GhbValue* ghb_parse_preset_path(const gchar *path); -gchar* ghb_preset_path_string(const GhbValue *path); -gboolean ghb_preset_is_custom(void); -gboolean ghb_lock_file(const gchar *name); +void ghb_presets_list_init(signal_user_data_t *ud, + const hb_preset_index_t *path); int ghb_find_pid_file(); -void ghb_unlink_pid_file(int pid); void ghb_write_pid_file(); GhbValue* ghb_get_current_preset(signal_user_data_t *ud); -GhbValue* ghb_get_current_preset_path(signal_user_data_t *ud); void ghb_preset_to_settings(GhbValue *settings, GhbValue *preset); void ghb_prefs_to_settings(GhbValue *settings); -void dump_preset_path(const gchar *msg, const GhbValue *path); GhbValue* ghb_read_settings_file(const gchar *path); void ghb_write_settings_file(const gchar *path, GhbValue *dict); diff --git a/gtk/src/queuehandler.c b/gtk/src/queuehandler.c index 876d49ec9..64421f8d9 100644 --- a/gtk/src/queuehandler.c +++ b/gtk/src/queuehandler.c @@ -168,10 +168,9 @@ add_to_queue_list(signal_user_data_t *ud, GhbValue *settings, GtkTreeIter *piter // Next line in the display // Preset: PresetName - gchar *preset; + const char *name; gboolean markers; gboolean preset_modified; - const GhbValue *path; const char *mux_id; const hb_container_t *mux; @@ -180,19 +179,17 @@ add_to_queue_list(signal_user_data_t *ud, GhbValue *settings, GtkTreeIter *piter mux = ghb_lookup_container_by_name(mux_id); preset_modified = ghb_dict_get_bool(settings, "preset_modified"); - path = ghb_dict_get_value(settings, "preset"); - preset = ghb_preset_path_string(path); + name = ghb_dict_get_string(settings, "PresetFullName"); markers = ghb_dict_get_bool(settings, "ChapterMarkers"); if (preset_modified) { - XPRINT(_("<b>Modified Preset Based On:</b> <small>%s</small>\n"), preset); + XPRINT(_("<b>Modified Preset Based On:</b> <small>%s</small>\n"), name); } else { - XPRINT(_("<b>Preset:</b> <small>%s</small>\n"), preset); + XPRINT(_("<b>Preset:</b> <small>%s</small>\n"), name); } - g_free(preset); // Next line in the display (Container type) // Format: XXX Container diff --git a/gtk/src/resources.c b/gtk/src/resources.c index 6683f1cd7..122a878d0 100644 --- a/gtk/src/resources.c +++ b/gtk/src/resources.c @@ -44,13 +44,6 @@ ghb_resource_init() ghb_dict_set(resources, "internal-defaults", val); gbytes = g_resource_lookup_data(data_res, - "/org/handbrake/data/standard_presets.json", 0, NULL); - data = g_bytes_get_data(gbytes, &data_size); - val = ghb_json_parse(data); - g_bytes_unref(gbytes); - ghb_dict_set(resources, "standard-presets", val); - - gbytes = g_resource_lookup_data(data_res, "/org/handbrake/data/widget.deps", 0, NULL); data = g_bytes_get_data(gbytes, &data_size); val = ghb_json_parse(data); diff --git a/gtk/src/standard_presets.json b/gtk/src/standard_presets.json deleted file mode 100644 index 41c7be767..000000000 --- a/gtk/src/standard_presets.json +++ /dev/null @@ -1,867 +0,0 @@ -[ - { - "ChildrenArray": [ - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - }, - { - "AudioBitrate": "160", - "AudioEncoder": "AC3 Passthru", - "AudioMixdown": "None", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 576, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 720, - "PresetDescription": "HandBrake's settings for compatibility with all Apple devices (including the iPod 6G and later). Includes Dolby Digital audio for surround sound.", - "PresetName": "Universal", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 20.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "3.0", - "VideoProfile": "baseline", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "fast", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 1, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 240, - "PictureKeepRatio": 1, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "off", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 320, - "PresetDescription": "HandBrake's settings for playback on the iPod with Video (all generations).", - "PresetName": "iPod", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 22.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "1.3", - "VideoProfile": "baseline", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 640, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 960, - "PresetDescription": "HandBrake's settings for handheld iOS devices (iPhone 4, iPod touch 3G and later).", - "PresetName": "iPhone & iPod touch", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 22.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "3.1", - "VideoProfile": "high", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 720, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 1280, - "PresetDescription": "HandBrake's settings for playback on the iPad (all generations).", - "PresetName": "iPad", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 20.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "3.1", - "VideoProfile": "high", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - }, - { - "AudioBitrate": "160", - "AudioEncoder": "AC3 Passthru", - "AudioMixdown": "None", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 720, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 960, - "PresetDescription": "HandBrake's settings for the original AppleTV. Includes Dolby Digital audio for surround sound. Also compatible with iOS devices released since 2009.", - "PresetName": "AppleTV", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 20.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "3.1", - "VideoProfile": "high", - "x264Option": "", - "VideoOptionExtra": "qpmin=4:cabac=0:ref=2:b-pyramid=none:weightb=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - }, - { - "AudioBitrate": "160", - "AudioEncoder": "AC3 Passthru", - "AudioMixdown": "None", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 720, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 1280, - "PresetDescription": "HandBrake's settings for the second-generation AppleTV. Includes Dolby Digital audio for surround sound. NOT compatible with the original AppleTV.", - "PresetName": "AppleTV 2", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 20.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "3.1", - "VideoProfile": "high", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - }, - { - "AudioBitrate": "160", - "AudioEncoder": "AC3 Passthru", - "AudioMixdown": "None", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 3, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 1080, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 1920, - "PresetDescription": "HandBrake's settings for the third-generation AppleTV. Includes Dolby Digital audio for surround sound. NOT compatible with the original AppleTV. May stutter on the second-generation AppleTV.", - "PresetName": "AppleTV 3", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 20.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "4.0", - "VideoProfile": "high", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "128", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 0, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 576, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 720, - "PresetDescription": "HandBrake's settings for midrange devices running Android 2.3 or later.", - "PresetName": "Android", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 22.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "3.0", - "VideoProfile": "main", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "128", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 0, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 720, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 1280, - "PresetDescription": "HandBrake's preset for tablets running Android 2.3 or later.", - "PresetName": "Android Tablet", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 22.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "3.1", - "VideoProfile": "main", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "128", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 0, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 720, - "PictureKeepRatio": 1, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "off", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 1280, - "PresetDescription": "HandBrake's preset for Windows Phone 8 devices", - "PresetName": "Windows Phone 8", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "30", - "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 22.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "3.1", - "VideoProfile": "main", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - } - ], - "Default": 0, - "Folder": true, - "PresetName": "Devices", - "Type": 0 - }, - { - "ChildrenArray": [ - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 1, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 0, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 0, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 0, - "PresetDescription": "HandBrake's normal, default settings.", - "PresetName": "Normal", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "Same as source", - "VideoFramerateMode": "vfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 20.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "4.0", - "VideoProfile": "main", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "veryfast", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - }, - { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, - "AudioEncoderFallback": "AC3 (ffmpeg)", - "AudioList": [ - { - "AudioBitrate": "160", - "AudioEncoder": "AAC (avcodec)", - "AudioMixdown": "Dolby Pro Logic II", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - }, - { - "AudioBitrate": "160", - "AudioEncoder": "AC3 Passthru", - "AudioMixdown": "None", - "AudioSamplerate": "Auto", - "AudioTrack": 1, - "AudioTrackDRCSlider": 0.0, - "AudioTrackGainSlider": 0.0 - } - ], - "ChapterMarkers": 1, - "Default": 0, - "FileFormat": "MP4 file", - "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, - "PictureBottomCrop": 0, - "PictureDeblock": 0, - "PictureDecomb": 2, - "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, - "PictureDeinterlaceCustom": "", - "PictureDenoiseFilter": "off", - "PictureDenoiseCustom": "", - "PictureDetelecine": 0, - "PictureDetelecineCustom": "", - "PictureHeight": 0, - "PictureKeepRatio": 0, - "PictureLeftCrop": 0, - "PictureModulus": 2, - "PicturePAR": "loose", - "PictureRightCrop": 0, - "PictureTopCrop": 0, - "PictureWidth": 0, - "PresetDescription": "HandBrake's general-purpose preset for High Profile H.264 video.", - "PresetName": "High Profile", - "Subtitles": "None", - "Type": 0, - "UsesPictureFilters": true, - "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", - "VideoEncoder": "H.264 (x264)", - "VideoFramerate": "Same as source", - "VideoFramerateMode": "vfr", - "VideoGrayScale": 0, - "VideoQualitySlider": 20.0, - "VideoQualityType": 2, - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, - "VideoLevel": "4.1", - "VideoProfile": "high", - "x264Option": "", - "VideoOptionExtra": "", - "VideoPreset": "medium", - "VideoTune": "", - "x264UseAdvancedOptions": 0 - } - ], - "Default": 0, - "Folder": true, - "PresetName": "Regular", - "Type": 0 - } -] diff --git a/gtk/src/values.c b/gtk/src/values.c index b413250cc..a1206d9d0 100644 --- a/gtk/src/values.c +++ b/gtk/src/values.c @@ -224,3 +224,32 @@ ghb_dict_get_string_xform(const GhbValue *dict, const gchar *key) return ghb_value_get_string_xform(value); } +void +ghb_dict_copy(GhbValue *dst, const GhbValue *src) +{ + GhbDictIter iter; + const char *key; + GhbValue *val, *dst_val; + + iter = ghb_dict_iter_init(src); + while (ghb_dict_iter_next(src, &iter, &key, &val)) + { + dst_val = ghb_dict_get(dst, key); + if (ghb_value_type(val) == GHB_DICT) + { + if (dst_val == NULL || ghb_value_type(dst_val) != GHB_DICT) + { + dst_val = ghb_value_dup(val); + ghb_dict_set(dst, key, dst_val); + } + else if (ghb_value_type(dst_val) == GHB_DICT) + { + ghb_dict_copy(dst_val, val); + } + } + else + { + ghb_dict_set(dst, key, ghb_value_dup(val)); + } + } +} diff --git a/gtk/src/values.h b/gtk/src/values.h index 87f7010cc..0f62bcc88 100644 --- a/gtk/src/values.h +++ b/gtk/src/values.h @@ -84,6 +84,8 @@ GhbValue* ghb_boolean_value(gboolean bval); void debug_show_value(GhbValue *gval); void debug_show_type(GhbType tp); +void ghb_dict_copy(GhbValue *dst, const GhbValue *src); + void ghb_dict_set_string(GhbValue *dict, const gchar *key, const gchar *sval); void ghb_dict_set_double(GhbValue *dict, const gchar *key, gdouble dval); void ghb_dict_set_int(GhbValue *dict, const gchar *key, gint64 ival); diff --git a/libhb/builtin_presets.h b/libhb/builtin_presets.h index b0b3e5cd8..fba7e1b67 100644 --- a/libhb/builtin_presets.h +++ b/libhb/builtin_presets.h @@ -4,52 +4,45 @@ const char hb_builtin_presets_json[] = " {\n" " \"ChildrenArray\": [\n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }, \n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"copy:ac3\", \n" " \"AudioMixdown\": \"none\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 576, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -59,13 +52,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's settings for compatibility with all Apple devices (including the iPod 6G and later). Includes Dolby Digital audio for surround sound.\", \n" " \"PresetName\": \"Universal\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"3.0\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"fast\", \n" @@ -73,49 +66,43 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 20.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 1, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": true, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 240, \n" -" \"PictureKeepRatio\": 1, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"off\", \n" @@ -125,13 +112,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's settings for playback on the iPod with Video (all generations).\", \n" " \"PresetName\": \"iPod\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"1.3\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -139,49 +126,43 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 22.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 640, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -191,13 +172,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's settings for handheld iOS devices (iPhone 4, iPod touch 3G and later).\", \n" " \"PresetName\": \"iPhone & iPod touch\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"3.1\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -205,49 +186,43 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 22.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 720, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -257,13 +232,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's settings for playback on the iPad (all generations).\", \n" " \"PresetName\": \"iPad\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"3.1\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -271,58 +246,51 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 20.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }, \n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"copy:ac3\", \n" " \"AudioMixdown\": \"none\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 720, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -332,13 +300,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's settings for the original AppleTV. Includes Dolby Digital audio for surround sound. Also compatible with iOS devices released since 2009.\", \n" " \"PresetName\": \"AppleTV\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"3.1\", \n" " \"VideoOptionExtra\": \"qpmin=4:cabac=0:ref=2:b-pyramid=none:weightb=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500\", \n" " \"VideoPreset\": \"medium\", \n" @@ -346,58 +314,51 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 20.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }, \n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"copy:ac3\", \n" " \"AudioMixdown\": \"none\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 720, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -407,13 +368,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's settings for the second-generation AppleTV. Includes Dolby Digital audio for surround sound. NOT compatible with the original AppleTV.\", \n" " \"PresetName\": \"AppleTV 2\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"3.1\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -421,58 +382,51 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 20.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }, \n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"copy:ac3\", \n" " \"AudioMixdown\": \"none\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 3, \n" +" \"PictureDecomb\": \"fast\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 1080, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -482,13 +436,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's settings for the third-generation AppleTV. Includes Dolby Digital audio for surround sound. NOT compatible with the original AppleTV. May stutter on the second-generation AppleTV.\", \n" " \"PresetName\": \"AppleTV 3\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"4.0\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -496,49 +450,43 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 20.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"128\", \n" +" \"AudioBitrate\": 128, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 0, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": false, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 576, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -548,13 +496,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's settings for midrange devices running Android 2.3 or later.\", \n" " \"PresetName\": \"Android\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"3.0\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -562,49 +510,43 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 22.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"128\", \n" +" \"AudioBitrate\": 128, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 0, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": false, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 720, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -614,13 +556,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's preset for tablets running Android 2.3 or later.\", \n" " \"PresetName\": \"Android Tablet\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"3.1\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -628,49 +570,43 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 22.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"128\", \n" +" \"AudioBitrate\": 128, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 0, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": false, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 720, \n" -" \"PictureKeepRatio\": 1, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"off\", \n" @@ -680,13 +616,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's preset for Windows Phone 8 devices\", \n" " \"PresetName\": \"Windows Phone 8\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"30\", \n" " \"VideoFramerateMode\": \"pfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"3.1\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -694,13 +630,12 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 22.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }\n" " ], \n" -" \"Default\": 0, \n" " \"Folder\": true, \n" " \"PresetName\": \"Devices\", \n" " \"Type\": 0\n" @@ -708,43 +643,37 @@ const char hb_builtin_presets_json[] = " {\n" " \"ChildrenArray\": [\n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 1, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": true, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 0, \n" +" \"PictureDecomb\": \"off\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 0, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -754,13 +683,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's normal, default settings.\", \n" " \"PresetName\": \"Normal\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"auto\", \n" " \"VideoFramerateMode\": \"vfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"4.0\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"veryfast\", \n" @@ -768,58 +697,51 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 20.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }, \n" " {\n" -" \"AudioAllowAACPass\": 1, \n" -" \"AudioAllowAC3Pass\": 1, \n" -" \"AudioAllowDTSHDPass\": 1, \n" -" \"AudioAllowDTSPass\": 1, \n" -" \"AudioAllowMP3Pass\": 1, \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"aac\", \n" " \"AudioMixdown\": \"dpl2\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }, \n" " {\n" -" \"AudioBitrate\": \"160\", \n" +" \"AudioBitrate\": 160, \n" " \"AudioEncoder\": \"copy:ac3\", \n" " \"AudioMixdown\": \"none\", \n" " \"AudioSamplerate\": \"auto\", \n" -" \"AudioTrack\": 1, \n" " \"AudioTrackDRCSlider\": 0.0, \n" " \"AudioTrackGainSlider\": 0.0\n" " }\n" " ], \n" -" \"ChapterMarkers\": 1, \n" -" \"Default\": 0, \n" +" \"ChapterMarkers\": true, \n" +" \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" -" \"Mp4HttpOptimize\": 0, \n" -" \"Mp4iPodCompatible\": 0, \n" -" \"PictureAutoCrop\": 1, \n" +" \"Mp4HttpOptimize\": false, \n" +" \"Mp4iPodCompatible\": false, \n" +" \"PictureAutoCrop\": true, \n" " \"PictureBottomCrop\": 0, \n" " \"PictureDeblock\": 0, \n" -" \"PictureDecomb\": 2, \n" +" \"PictureDecomb\": \"default\", \n" " \"PictureDecombCustom\": \"\", \n" -" \"PictureDecombDeinterlace\": 1, \n" -" \"PictureDeinterlace\": 0, \n" +" \"PictureDecombDeinterlace\": true, \n" +" \"PictureDeinterlace\": \"off\", \n" " \"PictureDeinterlaceCustom\": \"\", \n" " \"PictureDenoiseCustom\": \"\", \n" " \"PictureDenoiseFilter\": \"off\", \n" -" \"PictureDetelecine\": 0, \n" +" \"PictureDetelecine\": \"off\", \n" " \"PictureDetelecineCustom\": \"\", \n" " \"PictureHeight\": 0, \n" -" \"PictureKeepRatio\": 0, \n" +" \"PictureKeepRatio\": true, \n" " \"PictureLeftCrop\": 0, \n" " \"PictureModulus\": 2, \n" " \"PicturePAR\": \"loose\", \n" @@ -829,13 +751,13 @@ const char hb_builtin_presets_json[] = " \"PresetDescription\": \"HandBrake's general-purpose preset for High Profile H.264 video.\", \n" " \"PresetName\": \"High Profile\", \n" " \"Type\": 0, \n" -" \"UsesPictureFilters\": 1, \n" +" \"UsesPictureFilters\": true, \n" " \"UsesPictureSettings\": 1, \n" -" \"VideoAvgBitrate\": \"2500\", \n" +" \"VideoAvgBitrate\": 2500, \n" " \"VideoEncoder\": \"x264\", \n" " \"VideoFramerate\": \"auto\", \n" " \"VideoFramerateMode\": \"vfr\", \n" -" \"VideoGrayScale\": 0, \n" +" \"VideoGrayScale\": false, \n" " \"VideoLevel\": \"4.1\", \n" " \"VideoOptionExtra\": \"\", \n" " \"VideoPreset\": \"medium\", \n" @@ -843,13 +765,12 @@ const char hb_builtin_presets_json[] = " \"VideoQualitySlider\": 20.0, \n" " \"VideoQualityType\": 2, \n" " \"VideoTune\": \"\", \n" -" \"VideoTurboTwoPass\": 0, \n" -" \"VideoTwoPass\": 0, \n" +" \"VideoTurboTwoPass\": false, \n" +" \"VideoTwoPass\": false, \n" " \"x264Option\": \"\", \n" -" \"x264UseAdvancedOptions\": 0\n" +" \"x264UseAdvancedOptions\": false\n" " }\n" " ], \n" -" \"Default\": 0, \n" " \"Folder\": true, \n" " \"PresetName\": \"Regular\", \n" " \"Type\": 0\n" @@ -857,14 +778,6 @@ const char hb_builtin_presets_json[] = " ], \n" " \"PresetTemplate\": {\n" " \"Preset\": {\n" -" \"AudioAllowAACPass\": false, \n" -" \"AudioAllowAC3Pass\": true, \n" -" \"AudioAllowDTSHDPass\": false, \n" -" \"AudioAllowDTSPass\": false, \n" -" \"AudioAllowEAC3Pass\": false, \n" -" \"AudioAllowFLACPass\": false, \n" -" \"AudioAllowMP3Pass\": false, \n" -" \"AudioAllowTRUEHDPass\": false, \n" " \"AudioCopyMask\": [], \n" " \"AudioEncoderFallback\": \"ac3\", \n" " \"AudioLanguageList\": [\n" @@ -872,7 +785,7 @@ const char hb_builtin_presets_json[] = " ], \n" " \"AudioList\": [\n" " {\n" -" \"AudioBitrate\": \"192\", \n" +" \"AudioBitrate\": 192, \n" " \"AudioCompressionLevel\": -1.0, \n" " \"AudioDitherMethod\": \"auto\", \n" " \"AudioEncoder\": \"copy:ac3\", \n" @@ -888,9 +801,11 @@ const char hb_builtin_presets_json[] = " \"AudioSecondaryEncoderMode\": true, \n" " \"AudioTrackSelectionBehavior\": \"first\", \n" " \"ChapterMarkers\": true, \n" +" \"ChildrenArray\": [], \n" " \"Default\": false, \n" " \"FileFormat\": \"mp4\", \n" " \"Folder\": false, \n" +" \"FolderOpen\": false, \n" " \"Mp4HttpOptimize\": false, \n" " \"Mp4iPodCompatible\": false, \n" " \"PictureAutoCrop\": true, \n" diff --git a/libhb/hb.h b/libhb/hb.h index 215455cda..a838c943d 100644 --- a/libhb/hb.h +++ b/libhb/hb.h @@ -20,6 +20,7 @@ extern "C" { #include "hb_dict.h" #include "hb_json.h" #include "preset.h" +#include "plist.h" #include "param.h" /* hb_init() diff --git a/libhb/hb_dict.c b/libhb/hb_dict.c index 866803f58..634b25b09 100644 --- a/libhb/hb_dict.c +++ b/libhb/hb_dict.c @@ -32,10 +32,9 @@ hb_value_t * hb_value_dup(const hb_value_t *value) return json_deep_copy(value); } -void hb_value_incref(hb_value_t *value) +hb_value_t* hb_value_incref(hb_value_t *value) { - if (value == NULL) return; - json_incref(value); + return json_incref(value); } void hb_value_decref(hb_value_t *value) @@ -89,11 +88,6 @@ hb_value_t * hb_value_read_json(const char *path) { json_error_t error; hb_value_t *val = json_load_file(path, 0, &error); - if (val == NULL) - { - hb_error("hb_value_read_json: Failed, path (%s), error %s", - path, error.text); - } return val; } @@ -484,7 +478,7 @@ hb_value_t * hb_dict_iter_value(const hb_dict_iter_t iter) } int -hb_dict_iter_next_ex(hb_dict_t *dict, hb_dict_iter_t *iter, +hb_dict_iter_next_ex(const hb_dict_t *dict, hb_dict_iter_t *iter, const char **key, hb_value_t **val) { if (*iter == NULL) @@ -493,7 +487,7 @@ hb_dict_iter_next_ex(hb_dict_t *dict, hb_dict_iter_t *iter, *key = json_object_iter_key(*iter); if (val != NULL) *val = json_object_iter_value(*iter); - *iter = json_object_iter_next(dict, *iter); + *iter = json_object_iter_next((hb_dict_t*)dict, *iter); return 1; } diff --git a/libhb/hb_dict.h b/libhb/hb_dict.h index 2a4f71cfe..243d8885d 100644 --- a/libhb/hb_dict.h +++ b/libhb/hb_dict.h @@ -52,7 +52,8 @@ hb_value_t * hb_dict_get(const hb_dict_t * dict, const char * key); */ hb_dict_iter_t hb_dict_iter_init(const hb_dict_t *dict); hb_dict_iter_t hb_dict_iter_next(const hb_dict_t *dict, hb_dict_iter_t iter); -int hb_dict_iter_next_ex(hb_dict_t *dict, hb_dict_iter_t *iter, +int hb_dict_iter_next_ex(const hb_dict_t *dict, + hb_dict_iter_t *iter, const char **key, hb_value_t **val); /* get key from iter */ const char * hb_dict_iter_key(const hb_dict_iter_t iter); @@ -86,7 +87,7 @@ size_t hb_value_array_len(const hb_value_array_t *array); int hb_value_type(const hb_value_t *value); int hb_value_is_number(const hb_value_t *value); hb_value_t * hb_value_dup(const hb_value_t *value); -void hb_value_incref(hb_value_t *value); +hb_value_t * hb_value_incref(hb_value_t *value); void hb_value_decref(hb_value_t *value); void hb_value_free(hb_value_t **value); diff --git a/libhb/plist.c b/libhb/plist.c index f61014537..bc6c9d1bd 100644 --- a/libhb/plist.c +++ b/libhb/plist.c @@ -1,3 +1,12 @@ +/* plist.c + + Copyright (c) 2003-2015 HandBrake Team + This file is part of the HandBrake source code + Homepage: <http://handbrake.fr/>. + It may be used under the terms of the GNU General Public License v2. + For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html + */ + #include <stdio.h> #include <stdlib.h> #include <fcntl.h> @@ -454,10 +463,18 @@ text_data( { char *text = (char*)xtext; parse_data_t *pd = (parse_data_t*)ud; - if (pd->value) free(pd->value); - pd->value = malloc(len + 1); - strncpy(pd->value, text, len); - pd->value[len] = 0; + + int pos = 0; + if (pd->value != NULL) + { + pos = strlen(pd->value); + } + char *tmp = realloc(pd->value, pos + len + 1); + if (tmp == NULL) + return; + pd->value = tmp; + strncpy(pd->value + pos, text, len); + pd->value[pos + len] = 0; } static void diff --git a/libhb/plist.h b/libhb/plist.h index 901aeb4b0..47a5e5e08 100644 --- a/libhb/plist.h +++ b/libhb/plist.h @@ -1,3 +1,12 @@ +/* plist.h + + Copyright (c) 2003-2015 HandBrake Team + This file is part of the HandBrake source code + Homepage: <http://handbrake.fr/>. + It may be used under the terms of the GNU General Public License v2. + For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html + */ + #if !defined(_HB_PLIST_H_) #define _HB_PLIST_H_ diff --git a/libhb/preset.c b/libhb/preset.c index 97a647214..8a3f59059 100644 --- a/libhb/preset.c +++ b/libhb/preset.c @@ -1,4 +1,4 @@ -/* hb_preset.c +/* preset.c Copyright (c) 2003-2015 HandBrake Team This file is part of the HandBrake source code @@ -28,9 +28,254 @@ int hb_preset_version_micro; static hb_value_t *hb_preset_template = NULL; static hb_value_t *hb_presets = NULL; -static hb_value_t *hb_presets_custom = NULL; static hb_value_t *hb_presets_builtin = NULL; +static void preset_clean(hb_value_t *preset, hb_value_t *template); +static void preset_import(hb_value_t *preset, int major, int minor, int micro); + +enum +{ + PRESET_DO_SUCCESS, + PRESET_DO_FAIL, + PRESET_DO_PARTIAL, + PRESET_DO_NEXT, + PRESET_DO_SKIP, + PRESET_DO_DELETE, + PRESET_DO_DONE +}; + +typedef struct +{ + hb_preset_index_t path; +} preset_do_context_t; + +typedef struct +{ + preset_do_context_t do_ctx; + hb_value_t *template; +} preset_clean_context_t; + +typedef struct +{ + preset_do_context_t do_ctx; + int major; + int minor; + int micro; +} preset_import_context_t; + +typedef struct +{ + preset_do_context_t do_ctx; + const char *name; + int recurse; + int last_match_idx; +} preset_search_context_t; + +typedef int (*preset_do_f)(hb_value_t *preset, preset_do_context_t *ctx); + +static int preset_cmp_idx(hb_value_t *preset, int idx, const char *name) +{ + const char *next, *preset_name; + int ii, len; + + // Strip leading '/' + if (name[0] == '/') + name++; + + // Find the part of the "name" path we want to match. + for (ii = 0; ii < idx; ii++) + { + next = strchr(name, '/'); + if (next == NULL) + return PRESET_DO_SKIP; + next++; + name = next; + } + + // Find the end of the part we want to match + next = strchr(name, '/'); + if (next != NULL) + len = next - name; + else + len = strlen(name); + if (len <= 0) + return PRESET_DO_SKIP; + + preset_name = hb_value_get_string(hb_dict_get(preset, "PresetName")); + if (strlen(preset_name) > len) + len = strlen(preset_name); + + // If match found and it's the last component of the "name", success! + if (!strncmp(name, preset_name, len)) + { + if (name[len] == 0) + return PRESET_DO_SUCCESS; + else + return PRESET_DO_PARTIAL; + } + return PRESET_DO_NEXT; +} + +static int do_preset_search(hb_value_t *preset, preset_do_context_t *do_ctx) +{ + preset_search_context_t *ctx = (preset_search_context_t*)do_ctx; + int idx, result; + + idx = ctx->do_ctx.path.depth - 1; + if (ctx->last_match_idx >= 0 && idx > ctx->last_match_idx) + { + // If there was a previous partial match, try to continue the match + idx -= ctx->last_match_idx; + } + + result = preset_cmp_idx(preset, idx, ctx->name); + if (ctx->recurse && result == PRESET_DO_SKIP) + { + result = preset_cmp_idx(preset, 0, ctx->name); + ctx->last_match_idx = idx; + } + if (result == PRESET_DO_PARTIAL) + { + return PRESET_DO_NEXT; + } + else + { + ctx->last_match_idx = -1; + } + + return result; +} + +static int do_preset_import(hb_value_t *preset, preset_do_context_t *do_ctx) +{ + preset_import_context_t *ctx = (preset_import_context_t*)do_ctx; + preset_import(preset, ctx->major, ctx->minor, ctx->micro); + return PRESET_DO_NEXT; +} + +static int do_preset_clean(hb_value_t *preset, preset_do_context_t *do_ctx) +{ + preset_clean_context_t *ctx = (preset_clean_context_t*)do_ctx; + preset_clean(preset, ctx->template); + return PRESET_DO_NEXT; +} + +static int do_delete_builtin(hb_value_t *preset, preset_do_context_t *ctx) +{ + if (hb_value_get_int(hb_dict_get(preset, "Type")) == 0) + return PRESET_DO_DELETE; + return PRESET_DO_NEXT; +} + +static int do_clear_default(hb_value_t *preset, preset_do_context_t *ctx) +{ + hb_dict_set(preset, "Default", hb_value_bool(0)); + return PRESET_DO_NEXT; +} + +static int do_find_default(hb_value_t *preset, preset_do_context_t *ctx) +{ + if (!hb_value_get_bool(hb_dict_get(preset, "Folder")) && + hb_value_get_bool(hb_dict_get(preset, "Default"))) + { + return PRESET_DO_SUCCESS; + } + return PRESET_DO_NEXT; +} + +static int presets_do(preset_do_f do_func, hb_value_t *preset, + preset_do_context_t *ctx) +{ + int result; + hb_value_t *next; + + if (hb_value_type(preset) == HB_VALUE_TYPE_ARRAY) + { + // An array of presets, clean each one + int ii; + + for (ii = 0; ii < hb_value_array_len(preset); ) + { + ctx->path.index[ctx->path.depth-1] = ii; + next = hb_value_array_get(preset, ii); + result = presets_do(do_func, next, ctx); + if (result == PRESET_DO_DELETE) + { + hb_value_array_remove(preset, ii); + continue; + } + ii++; + if (result != PRESET_DO_NEXT) + return result; + } + return PRESET_DO_NEXT; + } + else if (hb_value_type(preset) == HB_VALUE_TYPE_DICT && + hb_dict_get(preset, "VersionMajor") != NULL) + { + // A packaged preset list + next = hb_dict_get(preset, "PresetList"); + return presets_do(do_func, next, ctx); + } + else if (hb_value_type(preset) == HB_VALUE_TYPE_DICT && + hb_value_get_bool(hb_dict_get(preset, "Folder"))) + { + // Perform do_func on the folder... + result = do_func(preset, ctx); + if (result != PRESET_DO_NEXT) + return result; + + // Then perform preset action on the children of the folder + ctx->path.depth++; + next = hb_dict_get(preset, "ChildrenArray"); + result = presets_do(do_func, next, ctx); + if (result == PRESET_DO_SUCCESS) + return result; + ctx->path.depth--; + return result; + } + else if (hb_value_type(preset) == HB_VALUE_TYPE_DICT && + hb_dict_get(preset, "PresetName") != NULL) + { + // An individual, non-folder, preset + return do_func(preset, ctx); + } + else + { + hb_error("Error: invalid preset format in presets_do()"); + return PRESET_DO_NEXT; + } + return PRESET_DO_DONE; +} + +hb_preset_index_t* hb_preset_index_init(const int *index, int depth) +{ + hb_preset_index_t *path; + path = malloc(sizeof(hb_preset_index_t)); + path->depth = depth; + if (index != NULL) + memcpy(path->index, index, depth * sizeof(int)); + return path; +} + +hb_preset_index_t* hb_preset_index_dup(const hb_preset_index_t *path) +{ + if (path == NULL) + return NULL; + return hb_preset_index_init(path->index, path->depth); +} + +void hb_preset_index_append(hb_preset_index_t *dst, + const hb_preset_index_t *src) +{ + int ii; + for (ii = 0; ii < src->depth && + dst->depth < HB_MAX_PRESET_FOLDER_DEPTH; ii++, dst->depth++) + { + dst->index[dst->depth] = src->index[ii]; + } +} + static int get_job_mux(hb_dict_t *job_dict) { int mux; @@ -59,13 +304,14 @@ static int get_job_mux(hb_dict_t *job_dict) return mux; } -static int get_audio_copy_mask(hb_dict_t * preset) +static int get_audio_copy_mask(const hb_dict_t * preset) { int mask = HB_ACODEC_PASS_FLAG; hb_value_array_t *copy_mask_array = hb_dict_get(preset, "AudioCopyMask"); if (copy_mask_array != NULL) { + mask = HB_ACODEC_PASS_FLAG; int count = hb_value_array_len(copy_mask_array); int ii; for (ii = 0; ii < count; ii++) @@ -99,25 +345,6 @@ static int get_audio_copy_mask(hb_dict_t * preset) mask |= codec; } } - else - { - mask |= hb_value_get_bool(hb_dict_get(preset, "AudioAllowMP3Pass")) * - HB_ACODEC_MP3; - mask |= hb_value_get_bool(hb_dict_get(preset, "AudioAllowAACPass")) * - HB_ACODEC_FFAAC; - mask |= hb_value_get_bool(hb_dict_get(preset, "AudioAllowAC3Pass")) * - HB_ACODEC_AC3; - mask |= hb_value_get_bool(hb_dict_get(preset, "AudioAllowDTSPass")) * - HB_ACODEC_DCA; - mask |= hb_value_get_bool(hb_dict_get(preset, "AudioAllowDTSHDPass")) * - HB_ACODEC_DCA_HD; - mask |= hb_value_get_bool(hb_dict_get(preset, "AudioAllowEAC3Pass")) * - HB_ACODEC_FFEAC3; - mask |= hb_value_get_bool(hb_dict_get(preset, "AudioAllowFLACPass")) * - HB_ACODEC_FFFLAC; - mask |= hb_value_get_bool(hb_dict_get(preset, "AudioAllowTRUEHDPass")) * - HB_ACODEC_FFTRUEHD; - } return mask; } @@ -158,7 +385,7 @@ static int find_audio_track(const hb_title_t *title, return -1; } -static int validate_audio_encoders(hb_dict_t *preset) +static int validate_audio_encoders(const hb_dict_t *preset) { hb_value_array_t * encoder_list = hb_dict_get(preset, "AudioList"); int count = hb_value_array_len(encoder_list); @@ -264,7 +491,7 @@ static int sanitize_audio_codec(int in_codec, int out_codec, return codec; } -static void add_audio_for_lang(hb_value_array_t *list, hb_dict_t *preset, +static void add_audio_for_lang(hb_value_array_t *list, const hb_dict_t *preset, hb_title_t *title, int mux, int copy_mask, int fallback, const char *lang, int behavior, int mode, hb_dict_t *track_dict) @@ -383,7 +610,7 @@ static void add_audio_for_lang(hb_value_array_t *list, hb_dict_t *preset, // This function assumes that Mux has already been initialized in // the job_dict int hb_preset_job_add_audio(hb_handle_t *h, int title_index, - hb_dict_t *preset, hb_dict_t *job_dict) + const hb_dict_t *preset, hb_dict_t *job_dict) { hb_title_t *title = hb_find_title_by_index(h, title_index); if (title == NULL) @@ -557,7 +784,7 @@ static void add_subtitle_for_lang(hb_value_array_t *list, hb_title_t *title, // This function assumes that the AudioList and Mux have already been // initialized in the job_dict int hb_preset_job_add_subtitles(hb_handle_t *h, int title_index, - hb_dict_t *preset, hb_dict_t *job_dict) + const hb_dict_t *preset, hb_dict_t *job_dict) { hb_title_t *title = hb_find_title_by_index(h, title_index); if (title == NULL) @@ -812,7 +1039,8 @@ static int get_video_framerate(hb_value_t *rate_value) * in json representation of a title. * @param preset - Preset to initialize job with */ -hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index, hb_dict_t *preset) +hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index, + const hb_dict_t *preset) { hb_title_t *title = hb_find_title_by_index(h, title_index); if (title == NULL) @@ -1433,6 +1661,8 @@ dict_clean(hb_value_t *dict, hb_value_t *template) if (val != NULL) preset_name = hb_value_get_string(val); + // Remove keys that are not in the template and translate compatible + // data types to the types used in the template. for (iter = hb_dict_iter_init(tmp); iter != HB_DICT_ITER_DONE; iter = hb_dict_iter_next(tmp, iter)) @@ -1506,6 +1736,28 @@ dict_clean(hb_value_t *dict, hb_value_t *template) } } hb_value_free(&tmp); + + if (!hb_value_get_bool(hb_dict_get(dict, "Folder"))) + { + // Add key/value pairs that are in the template but not in the dict. + for (iter = hb_dict_iter_init(template); + iter != HB_DICT_ITER_DONE; + iter = hb_dict_iter_next(template, iter)) + { + key = hb_dict_iter_key(iter); + template_val = hb_dict_iter_value(iter); + + if (hb_value_type(template_val) != HB_VALUE_TYPE_ARRAY && + hb_value_type(template_val) != HB_VALUE_TYPE_DICT) + { + val = hb_dict_get(dict, key); + if (val == NULL) + { + hb_dict_set(dict, key, hb_value_dup(template_val)); + } + } + } + } } static void preset_clean(hb_value_t *preset, hb_value_t *template) @@ -1538,6 +1790,11 @@ static void preset_clean(hb_value_t *preset, hb_value_t *template) val = hb_value_string(mux); hb_dict_set(preset, "FileFormat", val); } + else + { + const hb_container_t *c = hb_container_get_next(NULL); + muxer = c->format; + } val = hb_dict_get(preset, "VideoEncoder"); if (val != NULL) { @@ -1564,10 +1821,13 @@ static void preset_clean(hb_value_t *preset, hb_value_t *template) int fr = hb_video_framerate_get_from_name(s); if (fr < 0) { + if (strcasecmp(s, "same as source")) + { + hb_error("Preset %s: Invalid video framerate (%s)", + preset_name, s); + } val = hb_value_string("auto"); hb_dict_set(preset, "VideoFramerate", val); - hb_error("Preset %s: Invalid video framerate (%s)", - preset_name, s); } } } @@ -1609,7 +1869,7 @@ static void preset_clean(hb_value_t *preset, hb_value_t *template) } enc = hb_audio_encoder_get_short_name(acodec); val = hb_value_string(enc); - hb_dict_set(preset, "AudioEncoder", val); + hb_dict_set(adict, "AudioEncoder", val); } val = hb_dict_get(adict, "AudioSamplerate"); if (val != NULL) @@ -1618,13 +1878,13 @@ static void preset_clean(hb_value_t *preset, hb_value_t *template) s = hb_value_get_string(val); if (strcasecmp(s, "auto")) { - int sr = hb_video_framerate_get_from_name(s); + int sr = hb_audio_samplerate_get_from_name(s); if (sr < 0) { - val = hb_value_string("auto"); - hb_dict_set(preset, "AudioSamplerate", val); hb_error("Preset %s: Invalid audio samplerate (%s)", preset_name, s); + val = hb_value_string("auto"); + hb_dict_set(adict, "AudioSamplerate", val); } } } @@ -1650,57 +1910,320 @@ static void preset_clean(hb_value_t *preset, hb_value_t *template) static void presets_clean(hb_value_t *presets, hb_value_t *template) { - if (hb_value_type(presets) == HB_VALUE_TYPE_ARRAY) + preset_clean_context_t ctx; + ctx.do_ctx.path.depth = 1; + ctx.template = template; + presets_do(do_preset_clean, presets, (preset_do_context_t*)&ctx); +} + +void hb_presets_clean(hb_value_t *preset) +{ + presets_clean(preset, hb_preset_template); +} + +static const char* import_indexed_filter(int filter_id, int index) +{ + hb_filter_param_t *filter_presets; + filter_presets = hb_filter_param_get_presets(filter_id); + + int ii; + for (ii = 0; filter_presets[ii].name != NULL; ii++) { - // An array of presets, clean each one - int ii, count; - count = hb_value_array_len(presets); - for (ii = 0; ii < count; ii++) + if (filter_presets[ii].index == index) + break; + } + return filter_presets[ii].short_name; +} + +static void import_decomb(hb_value_t *preset) +{ + hb_value_t *val = hb_dict_get(preset, "PictureDecomb"); + if (hb_value_is_number(val)) + { + const char *s; + int index = hb_value_get_int(val); + s = import_indexed_filter(HB_FILTER_DECOMB, index); + if (s != NULL) + { + hb_dict_set(preset, "PictureDecomb", hb_value_string(s)); + } + else { - hb_value_t *preset = hb_value_array_get(presets, ii); - preset_clean(preset, template); + hb_error("Invalid decomb index %d", index); + hb_dict_set(preset, "PictureDecomb", hb_value_string("off")); } } - else if (hb_value_type(presets) == HB_VALUE_TYPE_DICT && - hb_dict_get(presets, "VersionMajor") != NULL) +} + +static void import_deint(hb_value_t *preset) +{ + hb_value_t *val = hb_dict_get(preset, "PictureDeinterlace"); + if (hb_value_is_number(val)) { - // A packaged preset list - hb_value_t *list = hb_dict_get(presets, "PresetList"); - presets_clean(list, template); + const char *s; + int index = hb_value_get_int(val); + s = import_indexed_filter(HB_FILTER_DEINTERLACE, index); + if (s != NULL) + { + hb_dict_set(preset, "PictureDeinterlace", hb_value_string(s)); + } + else + { + hb_error("Invalid deinterlace index %d", index); + hb_dict_set(preset, "PictureDeinterlace", hb_value_string("off")); + } } - else if (hb_value_type(presets) == HB_VALUE_TYPE_DICT && - hb_dict_get(presets, "PresetName") != NULL) +} + +static void import_detel(hb_value_t *preset) +{ + hb_value_t *val = hb_dict_get(preset, "PictureDetelecine"); + if (hb_value_is_number(val)) { - // An individual preset - preset_clean(presets, template); + const char *s; + int index = hb_value_get_int(val); + s = import_indexed_filter(HB_FILTER_DETELECINE, index); + if (s != NULL) + { + hb_dict_set(preset, "PictureDetelecine", hb_value_string(s)); + } + else + { + hb_error("Invalid detelecine index %d", index); + hb_dict_set(preset, "PictureDetelecine", hb_value_string("off")); + } } - else +} + +static void import_denoise(hb_value_t *preset) +{ + hb_value_t *val = hb_dict_get(preset, "PictureDenoise"); + if (hb_value_is_number(val)) + { + const char *s; + int index = hb_value_get_int(val); + s = import_indexed_filter(HB_FILTER_HQDN3D, index); + if (s != NULL) + { + hb_dict_set(preset, "PictureDenoiseFilter", + hb_value_string("hqdn3d")); + hb_dict_set(preset, "PictureDenoisePreset", hb_value_string(s)); + } + else + { + if (index != 0) + hb_error("Invalid denoise index %d", index); + hb_dict_set(preset, "PictureDenoiseFilter", hb_value_string("off")); + } + } +} + +static void import_pic(hb_value_t *preset) +{ + if (hb_value_get_bool(hb_dict_get(preset, "UsesMaxPictureSettings"))) + { + // UsesMaxPictureSettings was deprecated + hb_dict_set(preset, "UsesPictureSettings", hb_value_int(2)); + } + + hb_value_t *val = hb_dict_get(preset, "PicturePAR"); + if (hb_value_is_number(val)) + { + const char *s; + int pic_par = hb_value_get_int(val); + switch (pic_par) + { + default: + case 0: + s = "off"; + break; + case 1: + s = "strict"; + break; + case 2: + s = "loose"; + break; + case 3: + s = "custom"; + break; + } + hb_dict_set(preset, "PicturePAR", hb_value_string(s)); + } +} + +static void import_audio(hb_value_t *preset) +{ + hb_value_t *copy = hb_dict_get(preset, "AudioCopyMask"); + if (copy != NULL) + return; + + copy = hb_value_array_init(); + hb_dict_set(preset, "AudioCopyMask", copy); + if (hb_value_get_bool(hb_dict_get(preset, "AudioAllowMP3Pass"))) + hb_value_array_append(copy, hb_value_string("copy:mp3")); + if (hb_value_get_bool(hb_dict_get(preset, "AudioAllowAACPass"))) + hb_value_array_append(copy, hb_value_string("copy:aac")); + if (hb_value_get_bool(hb_dict_get(preset, "AudioAllowAC3Pass"))) + hb_value_array_append(copy, hb_value_string("copy:ac3")); + if (hb_value_get_bool(hb_dict_get(preset, "AudioAllowDTSPass"))) + hb_value_array_append(copy, hb_value_string("copy:dts")); + if (hb_value_get_bool(hb_dict_get(preset, "AudioAllowDTSHDPass"))) + hb_value_array_append(copy, hb_value_string("copy:dtshd")); + if (hb_value_get_bool(hb_dict_get(preset, "AudioAllowEAC3Pass"))) + hb_value_array_append(copy, hb_value_string("copy:eac3")); + if (hb_value_get_bool(hb_dict_get(preset, "AudioAllowFLACPass"))) + hb_value_array_append(copy, hb_value_string("copy:flac")); + if (hb_value_get_bool(hb_dict_get(preset, "AudioAllowTRUEHDPass"))) + hb_value_array_append(copy, hb_value_string("copy:truehd")); +} + +static void import_video(hb_value_t *preset) +{ + hb_value_t *val; + + if ((val = hb_dict_get(preset, "x264Preset")) != NULL) + hb_dict_set(preset, "VideoPreset", hb_value_dup(val)); + if ((val = hb_dict_get(preset, "x264Tune")) != NULL) + hb_dict_set(preset, "VideoTune", hb_value_dup(val)); + if ((val = hb_dict_get(preset, "h264Profile")) != NULL) + hb_dict_set(preset, "VideoProfile", hb_value_dup(val)); + if ((val = hb_dict_get(preset, "h264Level")) != NULL) + hb_dict_set(preset, "VideoLevel", hb_value_dup(val)); + if ((val = hb_dict_get(preset, "x264OptionExtra")) != NULL) + hb_dict_set(preset, "VideoOptionExtra", hb_value_dup(val)); + + if (hb_value_get_int(hb_dict_get(preset, "VideoQualityType")) == 0) + { + // Target size no longer supported + hb_dict_set(preset, "VideoQualityType", hb_value_int(1)); + } + + if (hb_value_get_bool(hb_dict_get(preset, "VideoFrameratePFR"))) + { + hb_dict_set(preset, "VideoFramerateMode", hb_value_string("pfr")); + } + else if (hb_value_get_bool(hb_dict_get(preset, "VideoFramerateCFR"))) + { + hb_dict_set(preset, "VideoFramerateMode", hb_value_string("cfr")); + } + else if (hb_value_get_bool(hb_dict_get(preset, "VideoFramerateVFR"))) + { + hb_dict_set(preset, "VideoFramerateMode", hb_value_string("vfr")); + } + + const char *enc; + int codec; + enc = hb_value_get_string(hb_dict_get(preset, "VideoEncoder")); + codec = hb_video_encoder_get_from_name(enc); + if (codec & HB_VCODEC_FFMPEG_MASK) { - hb_error("Error: invalid preset format in presets_clean()"); + if ((val = hb_dict_get(preset, "lavcOption")) != NULL) + hb_dict_set(preset, "VideoOptionExtra", hb_value_dup(val)); } } +static void preset_import(hb_value_t *preset, int major, int minor, int micro) +{ + if (!hb_value_get_bool(hb_dict_get(preset, "Folder"))) + { + if (major == 0 && minor == 0 && micro == 0) + { + // Convert legacy presets (before versioning introduced) + import_video(preset); + import_pic(preset); + import_audio(preset); + import_decomb(preset); + import_deint(preset); + import_detel(preset); + import_denoise(preset); + } + preset_clean(preset, hb_preset_template); + } +} + +int hb_presets_version(hb_value_t *preset, int *major, int *minor, int *micro) +{ + *major = 0; *minor = 0; *micro = 0; + if (hb_value_type(preset) == HB_VALUE_TYPE_DICT) + { + // Is this a single preset or a packaged collection of presets? + hb_value_t *val = hb_dict_get(preset, "PresetName"); + if (val == NULL) + { + val = hb_dict_get(preset, "VersionMajor"); + if (val != NULL) + { + *major = hb_value_get_int(hb_dict_get(preset, "VersionMajor")); + *minor = hb_value_get_int(hb_dict_get(preset, "VersionMinor")); + *micro = hb_value_get_int(hb_dict_get(preset, "VersionMicro")); + return 0; + } + } + } + return -1; +} + +void hb_presets_import(hb_value_t *preset) +{ + preset_import_context_t ctx; + + ctx.do_ctx.path.depth = 1; + hb_presets_version(preset, &ctx.major, &ctx.minor, &ctx.micro); + presets_do(do_preset_import, preset, (preset_do_context_t*)&ctx); +} + +char * hb_presets_import_json(const char *json) +{ + hb_value_t * dict = hb_value_json(json); + if (dict == NULL) + return NULL; + + hb_presets_import(dict); + char * result = hb_value_get_json(dict); + hb_value_free(&dict); + return result; +} + +char * hb_presets_clean_json(const char *json) +{ + hb_value_t * dict = hb_value_json(json); + if (dict == NULL) + return NULL; + + presets_clean(dict, hb_preset_template); + char * result = hb_value_get_json(dict); + hb_value_free(&dict); + return result; +} + // Note that unpackage does not make any copies. // In one increases the reference count. -static hb_value_t * preset_unpackage(hb_value_t *packaged_presets) +static hb_value_t * presets_unpackage(const hb_value_t *packaged_presets) { - // TODO: Verify compatible version number. - // Do any desired legacy translations. - if (hb_value_type(packaged_presets) == HB_VALUE_TYPE_ARRAY) + // Do any legacy translations. + hb_value_t *tmp = hb_value_dup(packaged_presets); + hb_presets_import(tmp); + if (hb_value_type(tmp) == HB_VALUE_TYPE_ARRAY) { // Not packaged - hb_value_incref(packaged_presets); - return packaged_presets; + return tmp; + } + if (hb_dict_get(tmp, "PresetName") != NULL) + { + // Bare single preset + return tmp; } - hb_value_t *presets = hb_dict_get(packaged_presets, "PresetList"); + hb_value_t *presets = hb_dict_get(tmp, "PresetList"); hb_value_incref(presets); + hb_value_free(&tmp); return presets; } -static hb_value_t * preset_package(hb_value_t *presets) +static hb_value_t * presets_package(const hb_value_t *presets) { hb_dict_t *packaged_presets; - if (hb_dict_get(presets, "VersionMajor") == NULL) + if (hb_value_type(presets) != HB_VALUE_TYPE_DICT || + hb_dict_get(presets, "VersionMajor") == NULL) { // Preset is not packaged packaged_presets = hb_dict_init(); @@ -1711,14 +2234,14 @@ static hb_value_t * preset_package(hb_value_t *presets) hb_dict_set(packaged_presets, "VersionMicro", hb_value_int(hb_preset_version_micro)); - // TODO: What else to we want in the preset containers header? + // TODO: What else do we want in the preset containers header? + hb_dict_t *tmp = hb_value_dup(presets); if (hb_value_type(presets) == HB_VALUE_TYPE_DICT) { - hb_value_array_t *tmp = hb_value_array_init(); - hb_value_array_append(tmp, presets); - presets = tmp; + hb_value_array_t *array = hb_value_array_init(); + hb_value_array_append(array, tmp); + tmp = array; } - hb_dict_t *tmp = hb_value_dup(presets); presets_clean(tmp, hb_preset_template); hb_dict_set(packaged_presets, "PresetList", tmp); } @@ -1745,12 +2268,17 @@ void hb_presets_builtin_init(void) hb_preset_template = hb_value_dup(hb_dict_get(template, "Preset")); hb_presets_builtin = hb_value_dup(hb_dict_get(dict, "PresetBuiltin")); - hb_value_free(&dict); + hb_presets_clean(hb_presets_builtin); - // Make a dup, never change contents of hb_presets_builtin - hb_presets = hb_value_dup(hb_presets_builtin); - hb_presets_custom = hb_value_array_init(); + hb_presets = hb_value_array_init(); + hb_value_free(&dict); +} +void hb_presets_current_version(int *major, int* minor, int *micro) +{ + *major = hb_preset_version_major; + *minor = hb_preset_version_minor; + *micro = hb_preset_version_micro; } int hb_presets_gui_init(void) @@ -1761,29 +2289,12 @@ int hb_presets_gui_init(void) #if defined(HB_PRESET_JSON_FILE) hb_get_user_config_filename(path, "%s", HB_PRESET_JSON_FILE); dict = hb_value_read_json(path); - if (dict != NULL) - { - hb_value_t *preset = preset_unpackage(dict); - // Unpackaging does some validity checks and can fail - if (preset == NULL) - return -1; - int result = hb_presets_add(preset); - hb_value_free(&preset); - hb_value_free(&dict); - return result; - } #endif #if defined(HB_PRESET_PLIST_FILE) if (dict == NULL) { hb_get_user_config_filename(path, "%s", HB_PRESET_PLIST_FILE); dict = hb_plist_parse_file(path); - if (dict != NULL) - { - int result = hb_presets_add(dict); - hb_value_free(&dict); - return result; - } } #endif if (dict == NULL) @@ -1797,6 +2308,15 @@ int hb_presets_gui_init(void) #endif return -1; } + else + { + preset_do_context_t ctx; + ctx.path.depth = 1; + presets_do(do_delete_builtin, dict, &ctx); + int result = hb_presets_add(dict); + hb_value_free(&dict); + return result; + } return -1; } @@ -1811,49 +2331,31 @@ char * hb_presets_builtin_get_json(void) return json; } -static hb_value_t * preset_lookup(hb_value_t *list, const char *name, - int def, int folder, int recurse) +// Lookup a preset in the preset list. The "name" may contain '/' +// separators to explicitely specify a preset within the preset lists +// folder structure. +// +// If 'recurse' is specified, a recursive search for the first component +// in the name will be performed. +// +// I assume that the actual preset name does not include any '/' +// +// A reference to the preset is returned +static hb_preset_index_t * preset_lookup_path(const char *name, int recurse) { - int count = hb_value_array_len(list); - int ii; - for (ii = 0; ii < count; ii++) - { - int d; - const char *n; - hb_dict_t *preset_dict = hb_value_array_get(list, ii); - n = hb_value_get_string(hb_dict_get(preset_dict, "PresetName")); - d = hb_value_get_bool(hb_dict_get(preset_dict, "Default")); - if (hb_value_get_bool(hb_dict_get(preset_dict, "Folder"))) - { - if (folder && !def && n != NULL && !strncmp(name, n, 80)) - return preset_dict; - - if (recurse) - { - hb_value_array_t *children; - children = hb_dict_get(preset_dict, "ChildrenArray"); - if (children == NULL) - continue; - preset_dict = preset_lookup(children, name, def, - folder, recurse); - if (preset_dict != NULL) - return preset_dict; - } - } - else if (!folder) - { - if (!def && n != NULL && !strncmp(n, name, 80)) - { - // preset is not a folder and we found a matching preset name - return preset_dict; - } - else if (def && d) - { - return preset_dict; - } - } - } - return NULL; + preset_search_context_t ctx; + int result; + + ctx.do_ctx.path.depth = 1; + ctx.name = name; + ctx.recurse = recurse; + ctx.last_match_idx = -1; + result = presets_do(do_preset_search, hb_presets, + (preset_do_context_t*)&ctx); + if (result != PRESET_DO_SUCCESS) + ctx.do_ctx.path.depth = 0; + + return hb_preset_index_dup(&ctx.do_ctx.path); } // Lookup a preset in the preset list. The "name" may contain '/' @@ -1864,182 +2366,128 @@ static hb_value_t * preset_lookup(hb_value_t *list, const char *name, // in the name will be performed. // // I assume that the actual preset name does not include any '/' -hb_value_t * hb_preset_get(const char *name, int recurse) +// +// A copy of the preset is returned +hb_preset_index_t * hb_preset_search_index(const char *name, int recurse) { - if (name == NULL || name[0] == 0) - { - // bad input. - return NULL; - } - - char *tmp = strdup(name); - char *part, *next; - hb_value_t *list; - - list = hb_presets; - part = tmp; - next = strchr(name, '/'); - if (next == NULL) - { - // Only preset name was specified, so do a recursive search - hb_value_t *preset = preset_lookup(list, part, 0, 0, recurse); - free(tmp); - if (preset == NULL) - { - return NULL; - } - return hb_value_dup(preset); - } - // Found folder separator in name, do explicit path search - while (part) - { - *next = 0; - next++; - if (next[0] == 0) - { - // name ends in a folder separator '/'. Invalid input - free(tmp); - return NULL; - } + return preset_lookup_path(name, recurse); +} - // We have a folder part. Lookup the folder. - // First try non-recursive so that we match top level folders first - hb_dict_t *folder = preset_lookup(list, part, 0, 1, 0); - if (folder == NULL && recurse) - { - // Try a recursive search for the folder - folder = preset_lookup(list, part, 0, 1, recurse); - } - if (folder == NULL) - { - // Not found - free(tmp); - return NULL; - } - list = hb_dict_get(folder, "ChildrenArray"); - if (list == NULL) - { - // Folder found, but it has no children - free(tmp); - return NULL; - } - // Folder found, continue the search - part = next; - next = strchr(name, '/'); - if (next == NULL) - { - // We have reached the final component of the path - // which is the preset name. Do a non-recursive search. - // If the preset is not in the specified folder, will - // return NULL - hb_value_t *preset = preset_lookup(list, part, 0, 0, 0); - free(tmp); - if (preset == NULL) - { - return NULL; - } - return hb_value_dup(preset); - } - } - // This should never be reached, but some compilers might complain - // without a final return. - free(tmp); - return NULL; +hb_value_t * hb_preset_search(const char *name, int recurse) +{ + hb_preset_index_t *path = preset_lookup_path(name, recurse); + hb_value_t *preset = hb_preset_get(path); + free(path); + return preset; } -char * hb_preset_get_json(const char *name, int recurse) +char * hb_preset_search_json(const char *name, int recurse) { hb_value_t * preset; char *json; - preset = hb_preset_get(name, recurse); + preset = hb_preset_search(name, recurse); if (preset == NULL) return NULL; json = hb_value_get_json(preset); - hb_value_free(&preset); return json; } -static hb_dict_t * find_first_preset(hb_value_array_t *list) +static hb_preset_index_t * lookup_default_index(hb_value_t *list) { - int count, ii; - count = hb_value_array_len(list); - for (ii = 0; ii < count; ii++) - { - hb_dict_t *preset_dict = hb_value_array_get(list, ii); - if (hb_value_get_bool(hb_dict_get(preset_dict, "Folder"))) - { - hb_value_array_t *children; - children = hb_dict_get(preset_dict, "ChildrenArray"); - if (children == NULL) - continue; - preset_dict = find_first_preset(children); - if (preset_dict != NULL) - return preset_dict; - } - else - { - return preset_dict; - } - } - return NULL; + preset_do_context_t ctx; + int result; + + ctx.path.depth = 1; + result = presets_do(do_find_default, list, &ctx); + if (result != PRESET_DO_SUCCESS) + ctx.path.depth = 0; + return hb_preset_index_dup(&ctx.path); +} + +hb_preset_index_t * hb_presets_get_default_index(void) +{ + hb_preset_index_t *path = lookup_default_index(hb_presets); + return path; } hb_dict_t * hb_presets_get_default(void) { - // Look for preset with 'Default' flag set - hb_value_t *preset = preset_lookup(hb_presets, NULL, 1, 0, 1); - if (preset == NULL) - { - // Look for preset named 'Normal' flag set - preset = preset_lookup(hb_presets, "Normal", 0, 0, 1); - if (preset == NULL) - { - // Just grab the first preset available - preset = find_first_preset(hb_presets); - if (preset == NULL) - return NULL; - } - } - return hb_value_dup(preset); + hb_preset_index_t *path = hb_presets_get_default_index(); + return hb_preset_get(path); } char * hb_presets_get_default_json(void) { - hb_value_t *preset = preset_lookup(hb_presets, NULL, 1, 0, 1); - if (preset == NULL) - return NULL; - return hb_value_get_json(preset); + // Look for default preset + hb_value_t *def = hb_presets_get_default(); + return hb_value_get_json(def); +} + +void hb_presets_clear_default() +{ + preset_do_context_t ctx; + ctx.path.depth = 1; + presets_do(do_clear_default, hb_presets, &ctx); } -// Return: -// 0 upon success -// 1 if preset name could not be found -int hb_presets_set_default(const char *name, int recurse) +void hb_presets_builtin_update(void) { - hb_value_t *preset = preset_lookup(hb_presets, NULL, 1, 0, 1); - if (preset != NULL) + preset_do_context_t ctx; + hb_preset_index_t *path; + hb_value_t *builtin; + int ii; + + ctx.path.depth = 1; + presets_do(do_delete_builtin, hb_presets, &ctx); + + builtin = hb_value_dup(hb_presets_builtin); + path = lookup_default_index(hb_presets); + if (path != NULL && path->depth != 0) { - // Mark old defalt as not - hb_dict_set(preset, "Default", hb_value_bool(0)); + // The "Default" preset is an existing custom preset. + // Clear the default preset in builtins + ctx.path.depth = 1; + presets_do(do_clear_default, builtin, &ctx); } - preset = preset_lookup(hb_presets, name, 0, 0, recurse); - if (preset == NULL) - return -1; - hb_dict_set(preset, "Default", hb_value_bool(1)); - return 0; + free(path); + + for (ii = hb_value_array_len(builtin) - 1; ii >= 0; ii--) + { + hb_value_t *dict; + dict = hb_value_array_get(builtin, ii); + hb_value_incref(dict); + hb_value_array_insert(hb_presets, 0, dict); + } + hb_value_free(&builtin); } int hb_presets_add(hb_value_t *preset) { + hb_preset_index_t *path; + int added = 0; + + if (preset == NULL) + return -1; + + preset = presets_unpackage(preset); if (preset == NULL) return -1; - // TODO: validity checking of input preset + + path = lookup_default_index(preset); + if (path != NULL && path->depth != 0) + { + // There is a "Default" preset in the preset(s) being added. + // Clear any existing default preset. + hb_presets_clear_default(); + } + free(path); + + int index = hb_value_array_len(hb_presets); if (hb_value_type(preset) == HB_VALUE_TYPE_DICT) { // A standalone preset or folder of presets. Add to preset array. - // Only allow custom presets to be added - if (hb_value_get_int(hb_dict_get(preset, "Type")) == 1) - hb_value_array_append(hb_presets_custom, hb_value_dup(preset)); + hb_value_array_append(hb_presets, hb_value_dup(preset)); + added++; } else if (hb_value_type(preset) == HB_VALUE_TYPE_ARRAY) { @@ -2049,48 +2497,69 @@ int hb_presets_add(hb_value_t *preset) for (ii = 0; ii < count; ii++) { hb_value_t *value = hb_value_array_get(preset, ii); - hb_value_array_append(hb_presets_custom, hb_value_dup(value)); + hb_value_array_append(hb_presets, hb_value_dup(value)); + added++; } } - // Reconstruct global list - hb_value_decref(hb_presets); - hb_presets = hb_value_dup(hb_presets_builtin); - // Append custom presets - int count = hb_value_array_len(hb_presets_custom); - int ii; - for (ii = 0; ii < count; ii++) + hb_value_free(&preset); + if (added == 0) { - hb_value_t *value = hb_value_array_get(hb_presets_custom, ii); - // Only allow custom presets to be added - if (hb_value_get_int(hb_dict_get(value, "Type")) == 1) - hb_value_array_append(hb_presets, hb_value_dup(value)); + return -1; } - return 0; + + return index; } int hb_presets_add_json(const char *json) { - hb_value_t *packaged_preset = hb_value_json(json); - hb_value_t *preset = preset_unpackage(packaged_preset); + hb_value_t *preset = hb_value_json(json); if (preset == NULL) return -1; int result = hb_presets_add(preset); hb_value_free(&preset); - hb_value_free(&packaged_preset); return result; } +int hb_presets_version_file(const char *filename, + int *major, int *minor, int *micro) +{ + int result; + + hb_value_t *preset = hb_value_read_json(filename); + if (preset == NULL) + preset = hb_plist_parse_file(filename); + if (preset == NULL) + return -1; + + result = hb_presets_version(preset, major, minor, micro); + hb_value_free(&preset); + + return result; +} + +hb_value_t* hb_presets_read_file(const char *filename) +{ + hb_value_t *preset = hb_value_read_json(filename); + if (preset == NULL) + preset = hb_plist_parse_file(filename); + if (preset == NULL) + return NULL; + + return preset; +} + int hb_presets_add_file(const char *filename) { - hb_value_t *packaged_preset = hb_value_read_json(filename); - hb_value_t *preset = preset_unpackage(packaged_preset); - // Unpackaging does some validity checks and can fail + hb_value_t *preset = hb_value_read_json(filename); + if (preset == NULL) + preset = hb_plist_parse_file(filename); if (preset == NULL) return -1; + int result = hb_presets_add(preset); hb_value_free(&preset); - hb_value_free(&packaged_preset); + return result; } @@ -2169,7 +2638,7 @@ int hb_presets_add_path(char * path) { int res = hb_presets_add_file(files[ii]); // return success if any one of the files is successfully loaded - if (res == 0) + if (res >= 0) result = res; } hb_closedir( dir ); @@ -2180,17 +2649,20 @@ int hb_presets_add_path(char * path) hb_value_t * hb_presets_get(void) { - return hb_value_dup(hb_presets); + return hb_presets; } char * hb_presets_get_json(void) { - return hb_value_get_json(hb_presets); + char * result; + hb_value_t *presets = hb_presets_get(); + result = hb_value_get_json(presets); + return result; } -int hb_preset_write_json(hb_value_t *preset, const char *path) +int hb_presets_write_json(const hb_value_t *preset, const char *path) { - hb_value_t *packaged_preset = preset_package(preset); + hb_value_t *packaged_preset = presets_package(preset); // Packaging does some validity checks and can fail if (packaged_preset == NULL) return -1; @@ -2199,21 +2671,247 @@ int hb_preset_write_json(hb_value_t *preset, const char *path) return result; } -char * hb_preset_package_json(hb_value_t *preset) +char * hb_presets_package_json(const hb_value_t *preset) { - hb_value_t *packaged_preset = preset_package(preset); + hb_value_t *packaged_preset = presets_package(preset); // Packaging does some validity checks and can fail if (packaged_preset == NULL) return NULL; - char *json = hb_value_get_json(packaged_preset); + char *out_json = hb_value_get_json(packaged_preset); hb_value_free(&packaged_preset); - return json; + return out_json; +} + +char * hb_presets_json_package(const char *in_json) +{ + hb_value_t *preset = hb_value_json(in_json); + hb_value_t *packaged_preset = presets_package(preset); + // Packaging does some validity checks and can fail + if (packaged_preset == NULL) + return NULL; + char *out_json = hb_value_get_json(packaged_preset); + hb_value_free(&packaged_preset); + hb_value_free(&preset); + return out_json; } void hb_presets_free(void) { hb_value_free(&hb_preset_template); hb_value_free(&hb_presets); - hb_value_free(&hb_presets_custom); hb_value_free(&hb_presets_builtin); } + +hb_value_t * +hb_presets_get_folder_children(const hb_preset_index_t *path) +{ + int ii, count, folder; + hb_value_t *dict; + + if (path == NULL) + return hb_presets; + + hb_value_t *presets = hb_presets; + for (ii = 0; ii < path->depth; ii++) + { + count = hb_value_array_len(presets); + if (path->index[ii] >= count) return NULL; + dict = hb_value_array_get(presets, path->index[ii]); + folder = hb_value_get_bool(hb_dict_get(dict, "Folder")); + if (!folder) + break; + presets = hb_dict_get(dict, "ChildrenArray"); + } + if (ii < path->depth) + return NULL; + return presets; +} + +hb_value_t * +hb_preset_get(const hb_preset_index_t *path) +{ + hb_value_t *folder = NULL; + + if (path == NULL || path->depth <= 0) + return NULL; + + hb_preset_index_t folder_path = *path; + folder_path.depth--; + folder = hb_presets_get_folder_children(&folder_path); + if (folder) + { + if (hb_value_array_len(folder) <= path->index[path->depth-1]) + { + hb_error("hb_preset_get: not found"); + } + else + { + return hb_value_array_get(folder, path->index[path->depth-1]); + } + } + else + { + hb_error("hb_preset_get: not found"); + } + return NULL; +} + +int +hb_preset_set(const hb_preset_index_t *path, const hb_value_t *dict) +{ + hb_value_t *folder = NULL; + + if (dict == NULL || path == NULL || path->depth <= 0) + return -1; + + hb_preset_index_t folder_path = *path; + folder_path.depth--; + folder = hb_presets_get_folder_children(&folder_path); + if (folder) + { + if (hb_value_array_len(folder) <= path->index[path->depth-1]) + { + hb_error("hb_preset_replace: not found"); + return -1; + } + else + { + hb_value_t *dup = hb_value_dup(dict); + presets_clean(dup, hb_preset_template); + hb_value_array_set(folder, path->index[path->depth-1], dup); + } + } + else + { + hb_error("hb_preset_replace: not found"); + return -1; + } + return 0; +} + +int hb_preset_insert(const hb_preset_index_t *path, const hb_value_t *dict) +{ + hb_value_t *folder = NULL; + + if (dict == NULL || path == NULL || path->depth < 0) + return -1; + + int index = path->index[path->depth - 1]; + hb_preset_index_t folder_path = *path; + folder_path.depth--; + folder = hb_presets_get_folder_children(&folder_path); + if (folder) + { + hb_value_t *dup = hb_value_dup(dict); + presets_clean(dup, hb_preset_template); + if (hb_value_array_len(folder) <= index) + { + index = hb_value_array_len(folder); + hb_value_array_append(folder, dup); + } + else + { + hb_value_array_insert(folder, index, dup); + } + } + else + { + hb_error("hb_preset_insert: not found"); + return -1; + } + return index; +} + +int hb_preset_append(const hb_preset_index_t *path, const hb_value_t *dict) +{ + hb_value_t *folder = NULL; + + if (dict == NULL) + return -1; + + folder = hb_presets_get_folder_children(path); + if (folder) + { + int index; + hb_value_t *dup = hb_value_dup(dict); + presets_clean(dup, hb_preset_template); + index = hb_value_array_len(folder); + hb_value_array_append(folder, dup); + return index; + } + else + { + hb_error("hb_preset_append: not found"); + return -1; + } + return 0; +} + +int +hb_preset_delete(const hb_preset_index_t *path) +{ + hb_value_t *folder = NULL; + + if (path == NULL) + return -1; + + hb_preset_index_t folder_path = *path; + folder_path.depth--; + folder = hb_presets_get_folder_children(&folder_path); + if (folder) + { + if (hb_value_array_len(folder) <= path->index[path->depth-1]) + { + hb_error("hb_preset_delete: not found"); + return -1; + } + else + { + hb_value_array_remove(folder, path->index[path->depth-1]); + } + } + else + { + hb_error("hb_preset_delete: not found"); + return -1; + } + return 0; +} + +int hb_preset_move(const hb_preset_index_t *src_path, + const hb_preset_index_t *dst_path) +{ + hb_value_t *src_folder = NULL; + hb_value_t *dst_folder = NULL; + + hb_preset_index_t src_folder_path = *src_path; + hb_preset_index_t dst_folder_path = *dst_path; + src_folder_path.depth--; + dst_folder_path.depth--; + src_folder = hb_presets_get_folder_children(&src_folder_path); + dst_folder = hb_presets_get_folder_children(&dst_folder_path); + if (src_folder == NULL || dst_folder == NULL) + { + hb_error("hb_preset_move: not found"); + return -1; + } + + hb_value_t *dict; + int src_index, dst_index; + + src_index = src_path->index[src_path->depth-1]; + dst_index = dst_path->index[src_path->depth-1]; + dict = hb_value_array_get(src_folder, src_index); + hb_value_incref(dict); + hb_value_array_remove(src_folder, src_index); + + // Be careful about indexes in the case that they are in the same folder + if (src_folder == dst_folder && src_index < dst_index) + dst_index--; + if (hb_value_array_len(dst_folder) <= dst_index) + hb_value_array_append(dst_folder, dict); + else + hb_value_array_insert(dst_folder, dst_index, dict); + + return 0; +} diff --git a/libhb/preset.h b/libhb/preset.h index 5e7c460b6..a24b45cf2 100644 --- a/libhb/preset.h +++ b/libhb/preset.h @@ -1,4 +1,4 @@ -/* hb_preset.h +/* preset.h Copyright (c) 2003-2015 HandBrake Team This file is part of the HandBrake source code @@ -12,28 +12,93 @@ #include "common.h" #include "hb_dict.h" +#define HB_MAX_PRESET_FOLDER_DEPTH 8 + +typedef struct hb_preset_index_s hb_preset_index_t; + +// A preset index is a list of indexes that specifies a path to a +// specific preset in a preset list. Since a preset list can have +// folders that contain sub-lists, multiple index values are needed +// to create a complete path. +struct hb_preset_index_s +{ + int depth; + int index[HB_MAX_PRESET_FOLDER_DEPTH]; +}; + +#ifdef __LIBHB__ +// Preset APIs reserved for libhb + // Initialize the hb_value_array_t that holds HandBrake builtin presets +// These presets come from a json string embedded in libhb and can be +// retrieved with hb_presets_builtin_get() after initialization. void hb_presets_builtin_init(void); -// Load presets from GUI presets file if possible -int hb_presets_gui_init(void); - -// Free all libhb presets +// Free all libhb presets. This should only be called when closing +// an hb_handle_t. void hb_presets_free(void); -// Get list of HandBrake builtin presets as hb_value_array_t +#endif // __LIBHB__ + +// Get the currently supported preset format version +void hb_presets_current_version(int *major, int* minor, int *micro); + +// Get the format version of a preset dict +int hb_presets_version(hb_value_t *preset, int *major, int *minor, int *micro); + +// Initialize a new preset index. "index" may be NULL +hb_preset_index_t * hb_preset_index_init(const int *index, int depth); + +// Duplicate a preset index +hb_preset_index_t * hb_preset_index_dup(const hb_preset_index_t *path); + +// Append one index to another +void hb_preset_index_append(hb_preset_index_t *dst, + const hb_preset_index_t *src); + +// Load presets list from GUI presets file if it exists. This should probably +// only be used by the CLI. +int hb_presets_gui_init(void); + +// Get HandBrake builtin presets list as hb_value_array_t hb_value_t * hb_presets_builtin_get(void); -// Get list of HandBrake builtin presets as json string +// Get HandBrake builtin presets list as json string char * hb_presets_builtin_get_json(void); -// Register new presets with libhb from -// hb_dict_t (single preset) or hb_value_array_t (list of presets) -int hb_presets_add(hb_value_t *preset); +// Load default builtin presets list over the top of any builtins in the +// current preset list. This should be used by a frontend when it recognizes +// that it's preset file is from an older version of HandBrake. +void hb_presets_builtin_update(void); + +// Clean presets. Removes unknown keys and normalizes values. +// This should be applied before exporting a preset and is applied +// for you by hb_presets_write_json() and hb_preset_package_json(). +void hb_presets_clean(hb_value_t *preset); + +// Clean json presets. Removes unknown keys and normalizes values. +// This should be applied before exporting a preset and is applied +// for you by hb_presets_write_json() and hb_preset_package_json(). +char * hb_presets_clean_json(const char *json); + +// Import a preset. Sanitizes and converts old key/value pairs +// to new key/value pairs. This is applied for you by hb_presets_add(), +// hb_presets_add_json(), hb_presets_add_file(), and hb_presets_add_path() +void hb_presets_import(hb_value_t *preset); + +// Import a json preset. Sanitizes and converts old key/value pairs +// to new key/value pairs. +char * hb_presets_import_json(const char *json); // Register new presets with libhb from json string int hb_presets_add_json(const char *json); +// Read a preset file. Does not add to internal preset list. +hb_value_t* hb_presets_read_file(const char *filename); + +// Register new presets with libhb from a preset dict +int hb_presets_add(hb_value_t *preset); + // Register new presets with libhb from json file int hb_presets_add_file(const char *filename); @@ -45,16 +110,21 @@ int hb_presets_add_path(char * path); // Get list of all presets registered with libhb as hb_value_array_t hb_value_t * hb_presets_get(void); + // Get list of all presets registered with libhb as json string char * hb_presets_get_json(void); // Initialize a job from the given title and preset hb_dict_t * hb_preset_job_init(hb_handle_t *h, int title_index, - hb_dict_t *preset); + const hb_dict_t *preset); + +// Reinitialize subtitles from preset defaults. int hb_preset_job_add_subtitles(hb_handle_t *h, int title_index, - hb_dict_t *preset, hb_dict_t *job_dict); + const hb_dict_t *preset, hb_dict_t *job_dict); + +// Reinitialize audio from preset defaults. int hb_preset_job_add_audio(hb_handle_t *h, int title_index, - hb_dict_t *preset, hb_dict_t *job_dict); + const hb_dict_t *preset, hb_dict_t *job_dict); // Lookup a preset in the preset list. The "name" may contain '/' // separators to explicitely specify a preset within the preset lists @@ -64,21 +134,37 @@ int hb_preset_job_add_audio(hb_handle_t *h, int title_index, // in the name will be performed. // // I assume that the actual preset name does not include any '/' -hb_value_t * hb_preset_get(const char *name, int recurse); -char * hb_preset_get_json(const char *name, int recurse); +hb_preset_index_t * hb_preset_search_index(const char *name, int recurse); +hb_value_t * hb_preset_search(const char *name, int recurse); +char * hb_preset_search_json(const char *name, int recurse); + +hb_value_t * hb_presets_get_folder_children(const hb_preset_index_t *path); +hb_value_t * hb_preset_get(const hb_preset_index_t *path); +int hb_preset_delete(const hb_preset_index_t *path); +int hb_preset_set(const hb_preset_index_t *path, + const hb_value_t *dict); +int hb_preset_insert(const hb_preset_index_t *path, + const hb_value_t *dict); +int hb_preset_append(const hb_preset_index_t *path, + const hb_value_t *dict); +int hb_preset_move(const hb_preset_index_t *src_path, + const hb_preset_index_t *dst_path); // Recursively lookup the preset that is marked as 'Default' -hb_dict_t * hb_presets_get_default(void); -char * hb_presets_get_default_json(void); - -// Set the preset that is marked as 'Default' -int hb_presets_set_default(const char *name, int recurse); +hb_dict_t * hb_presets_get_default(void); +char * hb_presets_get_default_json(void); +hb_preset_index_t * hb_presets_get_default_index(void); // Package the provided preset (wrap in dict and add version etc) // and write to json file -int hb_preset_write_json(hb_value_t *preset, const char *path); +int hb_presets_write_json(const hb_value_t *preset, const char *path); + // Package the provided preset (wrap in dict and add version etc) // and return as json string -char * hb_preset_package_json(hb_value_t *preset); +char * hb_presets_package_json(const hb_value_t *presets); + +// Package the provided json presets list (wrap in dict and add version etc) +// and return as json string +char * hb_presets_json_package(const char *json_presets); #endif // HB_PRESET_H diff --git a/libhb/preset_builtin.json b/libhb/preset_builtin.json index 5bf5d4d8a..cc16e0f89 100644 --- a/libhb/preset_builtin.json +++ b/libhb/preset_builtin.json @@ -2,52 +2,45 @@ { "ChildrenArray": [ { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 }, { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "copy:ac3", "AudioMixdown": "none", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 0, + "ChapterMarkers": true, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 576, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -57,13 +50,13 @@ "PresetDescription": "HandBrake's settings for compatibility with all Apple devices (including the iPod 6G and later). Includes Dolby Digital audio for surround sound.", "PresetName": "Universal", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "3.0", "VideoOptionExtra": "", "VideoPreset": "fast", @@ -71,49 +64,43 @@ "VideoQualitySlider": 20.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 0, + "ChapterMarkers": true, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 1, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": true, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 240, - "PictureKeepRatio": 1, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "off", @@ -123,13 +110,13 @@ "PresetDescription": "HandBrake's settings for playback on the iPod with Video (all generations).", "PresetName": "iPod", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "1.3", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -137,49 +124,43 @@ "VideoQualitySlider": 22.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 0, + "ChapterMarkers": true, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 640, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -189,13 +170,13 @@ "PresetDescription": "HandBrake's settings for handheld iOS devices (iPhone 4, iPod touch 3G and later).", "PresetName": "iPhone & iPod touch", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "3.1", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -203,49 +184,43 @@ "VideoQualitySlider": 22.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 0, + "ChapterMarkers": true, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 720, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -255,13 +230,13 @@ "PresetDescription": "HandBrake's settings for playback on the iPad (all generations).", "PresetName": "iPad", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "3.1", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -269,58 +244,51 @@ "VideoQualitySlider": 20.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 }, { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "copy:ac3", "AudioMixdown": "none", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 0, + "ChapterMarkers": true, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 720, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -330,13 +298,13 @@ "PresetDescription": "HandBrake's settings for the original AppleTV. Includes Dolby Digital audio for surround sound. Also compatible with iOS devices released since 2009.", "PresetName": "AppleTV", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "3.1", "VideoOptionExtra": "qpmin=4:cabac=0:ref=2:b-pyramid=none:weightb=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500", "VideoPreset": "medium", @@ -344,58 +312,51 @@ "VideoQualitySlider": 20.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 }, { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "copy:ac3", "AudioMixdown": "none", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 0, + "ChapterMarkers": true, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 720, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -405,13 +366,13 @@ "PresetDescription": "HandBrake's settings for the second-generation AppleTV. Includes Dolby Digital audio for surround sound. NOT compatible with the original AppleTV.", "PresetName": "AppleTV 2", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "3.1", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -419,58 +380,51 @@ "VideoQualitySlider": 20.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 }, { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "copy:ac3", "AudioMixdown": "none", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 0, + "ChapterMarkers": true, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 3, + "PictureDecomb": "fast", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 1080, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -480,13 +434,13 @@ "PresetDescription": "HandBrake's settings for the third-generation AppleTV. Includes Dolby Digital audio for surround sound. NOT compatible with the original AppleTV. May stutter on the second-generation AppleTV.", "PresetName": "AppleTV 3", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "4.0", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -494,49 +448,43 @@ "VideoQualitySlider": 20.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "128", + "AudioBitrate": 128, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 0, - "Default": 0, + "ChapterMarkers": false, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 576, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -546,13 +494,13 @@ "PresetDescription": "HandBrake's settings for midrange devices running Android 2.3 or later.", "PresetName": "Android", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "3.0", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -560,49 +508,43 @@ "VideoQualitySlider": 22.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "128", + "AudioBitrate": 128, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 0, - "Default": 0, + "ChapterMarkers": false, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 720, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -612,13 +554,13 @@ "PresetDescription": "HandBrake's preset for tablets running Android 2.3 or later.", "PresetName": "Android Tablet", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "3.1", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -626,49 +568,43 @@ "VideoQualitySlider": 22.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "128", + "AudioBitrate": 128, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 0, - "Default": 0, + "ChapterMarkers": false, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 720, - "PictureKeepRatio": 1, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "off", @@ -678,13 +614,13 @@ "PresetDescription": "HandBrake's preset for Windows Phone 8 devices", "PresetName": "Windows Phone 8", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "30", "VideoFramerateMode": "pfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "3.1", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -692,13 +628,12 @@ "VideoQualitySlider": 22.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false } ], - "Default": 0, "Folder": true, "PresetName": "Devices", "Type": 0 @@ -706,43 +641,37 @@ { "ChildrenArray": [ { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 1, + "ChapterMarkers": true, + "Default": true, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 0, + "PictureDecomb": "off", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 0, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -752,13 +681,13 @@ "PresetDescription": "HandBrake's normal, default settings.", "PresetName": "Normal", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "auto", "VideoFramerateMode": "vfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "4.0", "VideoOptionExtra": "", "VideoPreset": "veryfast", @@ -766,58 +695,51 @@ "VideoQualitySlider": 20.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false }, { - "AudioAllowAACPass": 1, - "AudioAllowAC3Pass": 1, - "AudioAllowDTSHDPass": 1, - "AudioAllowDTSPass": 1, - "AudioAllowMP3Pass": 1, "AudioEncoderFallback": "ac3", "AudioList": [ { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "aac", "AudioMixdown": "dpl2", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 }, { - "AudioBitrate": "160", + "AudioBitrate": 160, "AudioEncoder": "copy:ac3", "AudioMixdown": "none", "AudioSamplerate": "auto", - "AudioTrack": 1, "AudioTrackDRCSlider": 0.0, "AudioTrackGainSlider": 0.0 } ], - "ChapterMarkers": 1, - "Default": 0, + "ChapterMarkers": true, + "Default": false, "FileFormat": "mp4", "Folder": false, - "Mp4HttpOptimize": 0, - "Mp4iPodCompatible": 0, - "PictureAutoCrop": 1, + "Mp4HttpOptimize": false, + "Mp4iPodCompatible": false, + "PictureAutoCrop": true, "PictureBottomCrop": 0, "PictureDeblock": 0, - "PictureDecomb": 2, + "PictureDecomb": "default", "PictureDecombCustom": "", - "PictureDecombDeinterlace": 1, - "PictureDeinterlace": 0, + "PictureDecombDeinterlace": true, + "PictureDeinterlace": "off", "PictureDeinterlaceCustom": "", "PictureDenoiseCustom": "", "PictureDenoiseFilter": "off", - "PictureDetelecine": 0, + "PictureDetelecine": "off", "PictureDetelecineCustom": "", "PictureHeight": 0, - "PictureKeepRatio": 0, + "PictureKeepRatio": true, "PictureLeftCrop": 0, "PictureModulus": 2, "PicturePAR": "loose", @@ -827,13 +749,13 @@ "PresetDescription": "HandBrake's general-purpose preset for High Profile H.264 video.", "PresetName": "High Profile", "Type": 0, - "UsesPictureFilters": 1, + "UsesPictureFilters": true, "UsesPictureSettings": 1, - "VideoAvgBitrate": "2500", + "VideoAvgBitrate": 2500, "VideoEncoder": "x264", "VideoFramerate": "auto", "VideoFramerateMode": "vfr", - "VideoGrayScale": 0, + "VideoGrayScale": false, "VideoLevel": "4.1", "VideoOptionExtra": "", "VideoPreset": "medium", @@ -841,13 +763,12 @@ "VideoQualitySlider": 20.0, "VideoQualityType": 2, "VideoTune": "", - "VideoTurboTwoPass": 0, - "VideoTwoPass": 0, + "VideoTurboTwoPass": false, + "VideoTwoPass": false, "x264Option": "", - "x264UseAdvancedOptions": 0 + "x264UseAdvancedOptions": false } ], - "Default": 0, "Folder": true, "PresetName": "Regular", "Type": 0 diff --git a/libhb/preset_template.json b/libhb/preset_template.json index 30449e437..c0a650703 100644 --- a/libhb/preset_template.json +++ b/libhb/preset_template.json @@ -1,12 +1,4 @@ { - "AudioAllowMP3Pass": false, - "AudioAllowAACPass": false, - "AudioAllowAC3Pass": true, - "AudioAllowDTSPass": false, - "AudioAllowDTSHDPass": false, - "AudioAllowEAC3Pass": false, - "AudioAllowFLACPass": false, - "AudioAllowTRUEHDPass": false, "AudioCopyMask": [ ], "AudioEncoderFallback": "ac3", @@ -15,7 +7,7 @@ ], "AudioList": [ { - "AudioBitrate": "192", + "AudioBitrate": 192, "AudioCompressionLevel": -1.0, "AudioDitherMethod": "auto", "AudioEncoder": "copy:ac3", @@ -31,9 +23,12 @@ "AudioSecondaryEncoderMode": true, "AudioTrackSelectionBehavior": "first", "ChapterMarkers": true, + "ChildrenArray": [ + ], "Default": false, "FileFormat": "mp4", "Folder": false, + "FolderOpen": false, "Mp4HttpOptimize": false, "Mp4iPodCompatible": false, "PictureAutoCrop": true, diff --git a/libhb/work.c b/libhb/work.c index 3168e1fde..6d891b426 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -233,10 +233,19 @@ void hb_display_job_info(hb_job_t *job) sec_stop = (float)stop / 90000.0 - min_stop * 60; min_stop %= 60; - hb_log(" + title %d, start %02d:%02d:%02.2f stop %02d:%02d:%02.2f", - title->index, - hr_start, min_start, sec_start, - hr_stop, min_stop, sec_stop); + if (job->pts_to_stop) + { + hb_log(" + title %d, start %02d:%02d:%02.2f stop %02d:%02d:%02.2f", + title->index, + hr_start, min_start, sec_start, + hr_stop, min_stop, sec_stop); + } + else + { + hb_log(" + title %d, start %02d:%02d:%02.2f", + title->index, + hr_start, min_start, sec_start); + } } else if( job->frame_to_start || job->frame_to_stop ) { diff --git a/scripts/create_resources.py b/scripts/create_resources.py index 95921d317..26f7acd1c 100755 --- a/scripts/create_resources.py +++ b/scripts/create_resources.py @@ -58,7 +58,7 @@ def start_element_handler(tag, attr): elif fname == None: print >> sys.stderr, ( "Error: No such plist file %s" % fbase ) sys.exit(1) - elif tag == "string": + elif tag == "text": fbase = attr["file"] fname = find_file(fbase) key = attr["name"] @@ -72,6 +72,9 @@ def start_element_handler(tag, attr): elif fname == None: print >> sys.stderr, ( "Error: No such string file %s" % fbase ) sys.exit(1) + elif tag == "string": + key = attr["name"] + val = attr["value"] if val != None: if type(current) == types.DictType: diff --git a/test/test.c b/test/test.c index 1026eae93..eb4918319 100644 --- a/test/test.c +++ b/test/test.c @@ -255,7 +255,7 @@ int main( int argc, char ** argv ) char * version; hb_global_init(); - + hb_presets_builtin_update(); // Get utf8 command line if windows get_argv_utf8(&argc, &argv); @@ -326,12 +326,12 @@ int main( int argc, char ** argv ) } if (preset_export_file != NULL) { - hb_preset_write_json(preset_dict, preset_export_file); + hb_presets_write_json(preset_dict, preset_export_file); } else { char *json; - json = hb_preset_package_json(preset_dict); + json = hb_presets_package_json(preset_dict); fprintf(stdout, "%s\n", json); } // If the user requested to export a preset, but not to @@ -2776,7 +2776,7 @@ static hb_dict_t * PreparePreset(const char *preset_name) if (preset_name != NULL) { - preset = hb_preset_get(preset_name, 1 /*recurse*/); + preset = hb_preset_search(preset_name, 1 /*recurse*/); if (preset == NULL) { fprintf(stderr, "Invalid preset %s\n" @@ -2794,6 +2794,7 @@ static hb_dict_t * PreparePreset(const char *preset_name) fprintf(stderr, "Error loading presets! Aborting.\n"); return NULL; } + preset = hb_value_dup(preset); int subtitle_track_count = count_subtitles(subtracks); // Apply any overrides that can be made directly to the preset |