+ gval = ghb_value_new(mac_type);
+ if (!g_value_transform(sval, gval))
+ {
+ g_warning("can't transform");
+ ghb_value_free(gval);
+ ghb_value_free(sval);
+ return NULL;
+ }
+ ghb_value_free(sval);
+ return gval;
+ }
+ }
+ g_debug("Can't map value: (%s)", str);
+ g_free(str);
+ return NULL;
+}
+
+static void
+export_value_xlat(GValue *dict)
+{
+ GValue *lin_val, *gval;
+ const gchar *key;
+
+ key = "VideoEncoder";
+ lin_val = ghb_dict_lookup(dict, key);
+ gval = export_value_xlat2(vcodec_xlat, lin_val, G_TYPE_STRING);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "FileFormat";
+ lin_val = ghb_dict_lookup(dict, key);
+ gval = export_value_xlat2(container_xlat, lin_val, G_TYPE_STRING);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "VideoFramerate";
+ lin_val = ghb_dict_lookup(dict, key);
+ gval = export_value_xlat2(framerate_xlat, lin_val, G_TYPE_STRING);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "PictureDetelecine";
+ lin_val = ghb_dict_lookup(dict, key);
+ gval = export_value_xlat2(detel_xlat, lin_val, G_TYPE_INT);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "PictureDecomb";
+ lin_val = ghb_dict_lookup(dict, key);
+ gval = export_value_xlat2(decomb_xlat, lin_val, G_TYPE_INT);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "PictureDeinterlace";
+ lin_val = ghb_dict_lookup(dict, key);
+ gval = export_value_xlat2(deint_xlat, lin_val, G_TYPE_INT);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "PictureDenoise";
+ lin_val = ghb_dict_lookup(dict, key);
+ gval = export_value_xlat2(denoise_xlat, lin_val, G_TYPE_INT);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+
+ GValue *slist;
+ GValue *sdict;
+ gint count, ii;
+
+ slist = ghb_dict_lookup(dict, "SubtitleList");
+ count = ghb_array_len(slist);
+ for (ii = 0; ii < count; ii++)
+ {
+ sdict = ghb_array_get_nth(slist, ii);
+ key = "SubtitleLanguage";
+ lin_val = ghb_dict_lookup(sdict, key);
+ gval = export_subtitle_xlat2(lin_val);
+ if (gval)
+ ghb_dict_insert(sdict, g_strdup(key), gval);
+ }
+
+ GValue *alist;
+ GValue *adict;
+
+ alist = ghb_dict_lookup(dict, "AudioList");
+ count = ghb_array_len(alist);
+ for (ii = 0; ii < count; ii++)
+ {
+ adict = ghb_array_get_nth(alist, ii);
+ key = "AudioTrack";
+ lin_val = ghb_dict_lookup(adict, key);
+ gval = export_audio_track_xlat2(lin_val);
+ if (gval)
+ ghb_dict_insert(adict, g_strdup(key), gval);
+ key = "AudioEncoder";
+ lin_val = ghb_dict_lookup(adict, key);
+ gval = export_value_xlat2(acodec_xlat, lin_val, G_TYPE_STRING);
+ if (gval)
+ ghb_dict_insert(adict, g_strdup(key), gval);
+ key = "AudioSamplerate";
+ lin_val = ghb_dict_lookup(adict, key);
+ gval = export_value_xlat2(samplerate_xlat, lin_val, G_TYPE_STRING);
+ if (gval)
+ ghb_dict_insert(adict, g_strdup(key), gval);
+ key = "AudioMixdown";
+ lin_val = ghb_dict_lookup(adict, key);
+ gval = export_value_xlat2(mix_xlat, lin_val, G_TYPE_STRING);
+ if (gval)
+ ghb_dict_insert(adict, g_strdup(key), gval);
+ }
+}
+
+
+static GValue*
+import_value_xlat2(
+ GValue *defaults,
+ value_map_t *value_map,
+ const gchar *key,
+ GValue *mac_val)
+{
+ GValue *gval, *def_val;
+
+ if (mac_val == NULL) return NULL;
+ def_val = ghb_dict_lookup(defaults, key);
+ if (def_val)
+ {
+ gint ii;
+ gchar *str;
+ GValue *sval;
+
+ str = ghb_value_string(mac_val);
+ for (ii = 0; value_map[ii].mac_val; ii++)
+ {
+ if (strcmp(str, value_map[ii].mac_val) == 0)
+ {
+ sval = ghb_string_value_new(value_map[ii].lin_val);
+ g_free(str);
+ gval = ghb_value_new(G_VALUE_TYPE(def_val));
+ if (!g_value_transform(sval, gval))
+ {
+ g_warning("can't transform");
+ ghb_value_free(gval);
+ ghb_value_free(sval);
+ return NULL;
+ }
+ ghb_value_free(sval);
+ return gval;
+ }
+ }
+ g_free(str);
+ }
+ else
+ {
+ gint ii;
+ gchar *str;
+ GValue *sval;
+
+ str = ghb_value_string(mac_val);
+ for (ii = 0; value_map[ii].mac_val; ii++)
+ {
+ if (strcmp(str, value_map[ii].mac_val) == 0)
+ {
+ sval = ghb_string_value_new(value_map[ii].lin_val);
+ g_free(str);
+ gval = ghb_value_new(G_VALUE_TYPE(mac_val));
+ if (!g_value_transform(sval, gval))
+ {
+ g_warning("can't transform");
+ ghb_value_free(gval);
+ ghb_value_free(sval);
+ return NULL;
+ }
+ ghb_value_free(sval);
+ return gval;
+ }
+ }
+ g_free(str);
+ }
+ return NULL;
+}
+
+static void
+import_value_xlat(GValue *dict)
+{
+ GValue *defaults, *mac_val, *gval;
+ const gchar *key;
+
+ defaults = plist_get_dict(internalPlist, "Presets");
+ key = "VideoEncoder";
+ mac_val = ghb_dict_lookup(dict, key);
+ gval = import_value_xlat2(defaults, vcodec_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "FileFormat";
+ mac_val = ghb_dict_lookup(dict, key);
+ gval = import_value_xlat2(defaults, container_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "VideoFramerate";
+ mac_val = ghb_dict_lookup(dict, key);
+ gval = import_value_xlat2(defaults, framerate_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "PictureDetelecine";
+ mac_val = ghb_dict_lookup(dict, key);
+ gval = import_value_xlat2(defaults, detel_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "PictureDecomb";
+ mac_val = ghb_dict_lookup(dict, key);
+ gval = import_value_xlat2(defaults, decomb_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "PictureDeinterlace";
+ mac_val = ghb_dict_lookup(dict, key);
+ gval = import_value_xlat2(defaults, deint_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+ key = "PictureDenoise";
+ mac_val = ghb_dict_lookup(dict, key);
+ gval = import_value_xlat2(defaults, denoise_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(dict, g_strdup(key), gval);
+
+
+ GValue *sdeflist;
+ GValue *sdefaults;
+ GValue *slist;
+ GValue *sdict;
+ gint count, ii;
+
+ sdeflist = ghb_dict_lookup(defaults, "SubtitleList");
+ if (sdeflist)
+ {
+ slist = ghb_dict_lookup(dict, "SubtitleList");
+ if (slist)
+ {
+ sdefaults = ghb_array_get_nth(sdeflist, 0);
+ count = ghb_array_len(slist);
+ for (ii = 0; ii < count; ii++)
+ {
+ sdict = ghb_array_get_nth(slist, ii);
+ key = "SubtitleLanguage";
+ mac_val = ghb_dict_lookup(sdict, key);
+ gval = import_subtitle_xlat2(mac_val);
+ if (gval)
+ ghb_dict_insert(sdict, g_strdup(key), gval);
+ }
+
+ }
+ else
+ {
+ key = "Subtitles";
+ mac_val = ghb_dict_lookup(dict, key);
+ slist = ghb_array_value_new(8);
+ ghb_dict_insert(dict, g_strdup("SubtitleList"), slist);
+ if (mac_val)
+ {
+ gchar *lang;
+
+ gval = import_subtitle_xlat2(mac_val);
+ lang = ghb_value_string(gval);
+ if (lang && strcasecmp(lang, "none") != 0 && !slist)
+ {
+ sdict = ghb_dict_value_new();
+ ghb_array_append(slist, sdict);
+ ghb_dict_insert(sdict, g_strdup("SubtitleLanguage"), gval);
+ gval = ghb_dict_lookup(dict, "SubtitlesForced");
+ if (gval != NULL)
+ {
+ ghb_dict_insert(sdict, g_strdup("SubtitleForced"),
+ ghb_value_dup(gval));
+ }
+ else
+ {
+ ghb_dict_insert(sdict, g_strdup("SubtitleForced"),
+ ghb_boolean_value_new(FALSE));
+ }
+ ghb_dict_insert(sdict, g_strdup("SubtitleBurned"),
+ ghb_boolean_value_new(TRUE));
+ ghb_dict_insert(sdict, g_strdup("SubtitleDefaultTrack"),
+ ghb_boolean_value_new(FALSE));
+ }
+ else
+ {
+ ghb_value_free(gval);
+ }
+ if (lang)
+ g_free(lang);
+ }
+ }
+ }
+ ghb_dict_remove(dict, "Subtitles");
+ ghb_dict_remove(dict, "SubtitlesForced");
+
+
+ GValue *alist;
+ GValue *adict;
+ GValue *adefaults;
+ GValue *adeflist;
+
+ adeflist = ghb_dict_lookup(defaults, "AudioList");
+ if (adeflist)
+ {
+ adefaults = ghb_array_get_nth(adeflist, 0);
+ alist = ghb_dict_lookup(dict, "AudioList");
+ count = ghb_array_len(alist);
+ for (ii = 0; ii < count; ii++)
+ {
+ adict = ghb_array_get_nth(alist, ii);
+ key = "AudioTrack";
+ mac_val = ghb_dict_lookup(adict, key);
+ gval = import_audio_track_xlat2(mac_val);
+ if (gval)
+ ghb_dict_insert(adict, g_strdup(key), gval);
+ key = "AudioEncoder";
+ mac_val = ghb_dict_lookup(adict, key);
+ gval = import_value_xlat2(adefaults, acodec_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(adict, g_strdup(key), gval);
+ key = "AudioSamplerate";
+ mac_val = ghb_dict_lookup(adict, key);
+ gval = import_value_xlat2(adefaults, samplerate_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(adict, g_strdup(key), gval);
+ key = "AudioMixdown";
+ mac_val = ghb_dict_lookup(adict, key);
+ gval = import_value_xlat2(adefaults, mix_xlat, key, mac_val);
+ if (gval)
+ ghb_dict_insert(adict, g_strdup(key), gval);
+
+ mac_val = ghb_dict_lookup(adict, "AudioTrackDRCSlider");
+ if (mac_val != NULL)
+ {
+ gdouble drc;
+ drc = ghb_value_double(mac_val);
+ if (drc < 1.0 && drc > 0.0)
+ {
+ ghb_dict_insert(adict, g_strdup("AudioTrackDRCSlider"),
+ ghb_double_value_new(0.0));
+ }
+ }
+ }
+ }
+}
+
+static void
+import_xlat_preset(GValue *dict)
+{
+ gboolean uses_max;
+ gint uses_pic;
+ gint par;
+ gint vqtype;
+
+ g_debug("import_xlat_preset ()");
+ uses_max = ghb_value_boolean(
+ preset_dict_get_value(dict, "UsesMaxPictureSettings"));
+ uses_pic = ghb_value_int(
+ preset_dict_get_value(dict, "UsesPictureSettings"));
+ par = ghb_value_int(preset_dict_get_value(dict, "PicturePAR"));
+ vqtype = ghb_value_int(preset_dict_get_value(dict, "VideoQualityType"));
+
+ if (uses_max || uses_pic == 2)
+ {
+ ghb_dict_insert(dict, g_strdup("autoscale"),
+ ghb_boolean_value_new(TRUE));
+ }
+ switch (par)
+ {
+ case 0:
+ {
+ if (ghb_dict_lookup(dict, "PictureModulus") == NULL)
+ ghb_dict_insert(dict, g_strdup("PictureModulus"),
+ ghb_int_value_new(16));
+ } break;
+ case 1:
+ {
+ ghb_dict_insert(dict, g_strdup("PictureModulus"),
+ ghb_int_value_new(1));
+ } break;
+ case 2:
+ {
+ if (ghb_dict_lookup(dict, "PictureModulus") == NULL)
+ ghb_dict_insert(dict, g_strdup("PictureModulus"),
+ ghb_int_value_new(16));
+ } break;
+ default:
+ {
+ if (ghb_dict_lookup(dict, "PictureModulus") == NULL)
+ ghb_dict_insert(dict, g_strdup("PictureModulus"),
+ ghb_int_value_new(16));
+ } break;
+ }
+ // VideoQualityType/0/1/2 - vquality_type_/target/bitrate/constant
+ switch (vqtype)
+ {
+ case 0:
+ {
+ ghb_dict_insert(dict, g_strdup("vquality_type_target"),
+ ghb_boolean_value_new(TRUE));
+ ghb_dict_insert(dict, g_strdup("vquality_type_bitrate"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("vquality_type_constant"),
+ ghb_boolean_value_new(FALSE));
+ } break;
+ case 1:
+ {
+ ghb_dict_insert(dict, g_strdup("vquality_type_target"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("vquality_type_bitrate"),
+ ghb_boolean_value_new(TRUE));
+ ghb_dict_insert(dict, g_strdup("vquality_type_constant"),
+ ghb_boolean_value_new(FALSE));
+ } break;
+ case 2:
+ {
+ ghb_dict_insert(dict, g_strdup("vquality_type_target"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("vquality_type_bitrate"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("vquality_type_constant"),
+ ghb_boolean_value_new(TRUE));
+ } break;
+ default:
+ {
+ ghb_dict_insert(dict, g_strdup("vquality_type_target"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("vquality_type_bitrate"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("vquality_type_constant"),
+ ghb_boolean_value_new(TRUE));
+ } break;
+ }
+ import_value_xlat(dict);
+
+ gdouble vquality;
+ const GValue *gval;
+
+ vquality = ghb_value_double(preset_dict_get_value(dict, "VideoQualitySlider"));
+ if (vquality > 0.0 && vquality < 1.0)
+ {
+ gint vcodec;
+
+ gval = preset_dict_get_value(dict, "VideoEncoder");
+ vcodec = ghb_lookup_combo_int("VideoEncoder", gval);
+ switch (vcodec)
+ {
+ case HB_VCODEC_X264:
+ {
+ vquality = 51. - vquality * 51.;
+ } break;
+
+ case HB_VCODEC_FFMPEG:
+ {
+ vquality = 31. - vquality * 30.;
+ } break;
+
+ case HB_VCODEC_THEORA:
+ {
+ vquality = vquality * 63.;
+ } break;
+
+ default:
+ {
+ vquality = 0.;
+ } break;
+ }
+ ghb_dict_insert(dict, g_strdup("VideoQualitySlider"),
+ ghb_double_value_new(vquality));
+ }
+}
+
+static void
+import_xlat_presets(GValue *presets)
+{
+ gint count, ii;
+ GValue *dict;
+ gboolean folder;
+
+ g_debug("import_xlat_presets ()");
+ if (presets == NULL) return;
+ count = ghb_array_len(presets);
+ for (ii = 0; ii < count; ii++)
+ {
+ dict = ghb_array_get_nth(presets, ii);
+ folder = ghb_value_boolean(preset_dict_get_value(dict, "Folder"));
+ if (folder)
+ {
+ GValue *nested;
+
+ nested = ghb_dict_lookup(dict, "ChildrenArray");
+ import_xlat_presets(nested);
+ }
+ else
+ {
+ import_xlat_preset(dict);
+ }
+ }
+}
+
+static void
+export_xlat_preset(GValue *dict)
+{
+ gboolean autoscale, target, br, constant;
+
+ g_debug("export_xlat_prest ()");
+ autoscale = ghb_value_boolean(preset_dict_get_value(dict, "autoscale"));
+ target = ghb_value_boolean(
+ preset_dict_get_value(dict, "vquality_type_target"));
+ br = ghb_value_boolean(
+ preset_dict_get_value(dict, "vquality_type_bitrate"));
+ constant = ghb_value_boolean(
+ preset_dict_get_value(dict, "vquality_type_constant"));
+
+ if (autoscale)
+ ghb_dict_insert(dict, g_strdup("UsesPictureSettings"),
+ ghb_int_value_new(2));
+ else
+ ghb_dict_insert(dict, g_strdup("UsesPictureSettings"),
+ ghb_int_value_new(1));
+
+ // VideoQualityType/0/1/2 - vquality_type_/target/bitrate/constant
+ if (target)
+ {
+ ghb_dict_insert(dict, g_strdup("VideoQualityType"),
+ ghb_int_value_new(0));
+ }
+ else if (br)
+ {
+ ghb_dict_insert(dict, g_strdup("VideoQualityType"),
+ ghb_int_value_new(1));
+ }
+ else if (constant)
+ {
+ ghb_dict_insert(dict, g_strdup("VideoQualityType"),
+ ghb_int_value_new(2));
+ }
+
+ GValue *alist, *adict;
+ gint count, ii;
+
+ alist = ghb_dict_lookup(dict, "AudioList");
+ count = ghb_array_len(alist);
+ for (ii = 0; ii < count; ii++)
+ {
+ gdouble drc;
+
+ adict = ghb_array_get_nth(alist, ii);
+ drc = ghb_value_double(
+ preset_dict_get_value(adict, "AudioTrackDRCSlider"));
+ if (drc < 1.0 && drc > 0.0)
+ {
+ ghb_dict_insert(adict, g_strdup("AudioTrackDRCSlider"),
+ ghb_double_value_new(0.0));
+ }
+ }
+
+ ghb_dict_remove(dict, "UsesMaxPictureSettings");
+ ghb_dict_remove(dict, "autoscale");
+ ghb_dict_remove(dict, "vquality_type_target");
+ ghb_dict_remove(dict, "vquality_type_bitrate");
+ ghb_dict_remove(dict, "vquality_type_constant");
+ export_value_xlat(dict);
+}
+
+static void
+export_xlat_presets(GValue *presets)
+{
+ gint count, ii;
+ GValue *dict;
+ gboolean folder;
+
+ if (presets == NULL) return;
+ count = ghb_array_len(presets);
+ for (ii = 0; ii < count; ii++)
+ {
+ dict = ghb_array_get_nth(presets, ii);
+ folder = ghb_value_boolean(preset_dict_get_value(dict, "Folder"));
+ if (folder)
+ {
+ GValue *nested;
+
+ nested = ghb_dict_lookup(dict, "ChildrenArray");
+ export_xlat_presets(nested);
+ }
+ else
+ {
+ export_xlat_preset(dict);
+ }
+ }
+}
+
+static guint prefs_timeout_id = 0;
+
+static gboolean
+delayed_store_prefs(gpointer data)
+{
+ store_plist(prefsPlist, "preferences");
+ prefs_timeout_id = 0;
+ return FALSE;
+}
+
+static void
+store_presets()
+{
+ GValue *export;
+
+ export = ghb_value_dup(presetsPlist);
+ export_xlat_presets(export);
+ store_plist(export, "presets");
+ ghb_value_free(export);
+}
+
+static void
+store_prefs(void)
+{
+ if (prefs_timeout_id != 0)
+ {
+ GMainContext *mc;
+ GSource *source;
+
+ mc = g_main_context_default();
+ source = g_main_context_find_source_by_id(mc, prefs_timeout_id);
+ if (source != NULL)
+ g_source_destroy(source);
+ }
+ prefs_timeout_id = g_timeout_add_seconds(1, (GSourceFunc)delayed_store_prefs, NULL);
+}
+
+void
+ghb_presets_reload(signal_user_data_t *ud)
+{
+ GValue *std_presets;
+ gint count, ii;
+ int *indices, len;
+
+ g_debug("ghb_presets_reload()\n");
+ std_presets = 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--)
+ {
+ GValue *std_dict;
+ GValue *copy_dict;
+ gint indices = 0;
+
+ std_dict = ghb_array_get_nth(std_presets, ii);
+ copy_dict = ghb_value_dup(std_dict);
+ ghb_dict_insert(copy_dict, g_strdup("PresetBuildNumber"),
+ ghb_int64_value_new(hb_get_build(NULL)));
+ ghb_presets_insert(presetsPlist, copy_dict, &indices, 1);
+ presets_list_insert(ud, &indices, 1);
+ }
+ import_xlat_presets(presetsPlist);
+ store_presets();
+}
+
+static gboolean
+check_old_presets()
+{
+ gint count, ii;
+
+ count = ghb_array_len(presetsPlist);
+ for (ii = count-1; ii >= 0; ii--)
+ {
+ GValue *dict;
+ GValue *type;
+
+ dict = ghb_array_get_nth(presetsPlist, ii);
+ type = ghb_dict_lookup(dict, "Type");
+ if (type == NULL)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+replace_standard_presets()
+{
+ GValue *std_presets;
+ int *indices, len;
+ gint count, ii;
+
+ count = ghb_array_len(presetsPlist);
+ for (ii = count-1; ii >= 0; ii--)
+ {
+ GValue *dict;
+ gint ptype;
+
+ dict = ghb_array_get_nth(presetsPlist, ii);
+ ptype = ghb_value_int(preset_dict_get_value(dict, "Type"));
+ if (ptype == PRESETS_BUILTIN)
+ {
+ gint indices = 0;
+ ghb_presets_remove(presetsPlist, &indices, 1);