summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2015-05-27 17:14:42 +0000
committerjstebbins <[email protected]>2015-05-27 17:14:42 +0000
commitf127b802bec8ca3394b155f15fde5519d04f4897 (patch)
tree77e9ea4dfafb8bac3a23ce01b0941fa74b04beeb
parent0863f72ab94e5ad4bb7652a5cbc6d2e7dc194420 (diff)
LinGui: use libhb to initialize job...
...and set some job settings as values change in the UI. This eliminates a large chunk of job setup code. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@7230 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--gtk/src/audiohandler.c67
-rw-r--r--gtk/src/callbacks.c251
-rw-r--r--gtk/src/ghb-3.12.ui18
-rw-r--r--gtk/src/ghb-3.14.ui18
-rw-r--r--gtk/src/ghb.ui18
-rw-r--r--gtk/src/hb-backend.c647
-rw-r--r--gtk/src/hb-backend.h4
-rw-r--r--gtk/src/presets.c49
-rw-r--r--gtk/src/presets.h1
-rw-r--r--gtk/src/preview.c20
-rw-r--r--gtk/src/queuehandler.c47
-rw-r--r--gtk/src/queuehandler.h1
-rw-r--r--gtk/src/settings.c181
-rw-r--r--gtk/src/settings.h17
-rw-r--r--gtk/src/subtitlehandler.c85
-rw-r--r--libhb/preset.c680
-rw-r--r--libhb/preset.h17
17 files changed, 923 insertions, 1198 deletions
diff --git a/gtk/src/audiohandler.c b/gtk/src/audiohandler.c
index 067300f1c..68a114d26 100644
--- a/gtk/src/audiohandler.c
+++ b/gtk/src/audiohandler.c
@@ -31,43 +31,6 @@ static void ghb_adjust_audio_rate_combos(signal_user_data_t *ud);
static gboolean block_updates = FALSE;
-static GhbValue *get_audio_settings(GhbValue *settings)
-{
- GhbValue *audio, *job;
- job = ghb_get_job_settings(settings);
- audio = ghb_dict_get(job, "Audio");
- if (audio == NULL)
- {
- audio = ghb_dict_new();
- ghb_dict_set(job, "Audio", audio);
- }
- return audio;
-}
-
-GhbValue *ghb_get_audio_settings(GhbValue *settings)
-{
- return get_audio_settings(settings);
-}
-
-
-static GhbValue *get_audio_list(GhbValue *settings)
-{
- GhbValue *audio_dict, *audio_list = NULL;
- audio_dict = get_audio_settings(settings);
- audio_list = ghb_dict_get(audio_dict, "AudioList");
- if (audio_list == NULL)
- {
- audio_list = ghb_array_new();
- ghb_dict_set(audio_dict, "AudioList", audio_list);
- }
- return audio_list;
-}
-
-GhbValue *ghb_get_audio_list(GhbValue *settings)
-{
- return get_audio_list(settings);
-}
-
static void enable_quality_widget(signal_user_data_t *ud, int acodec)
{
GtkWidget *widget1, *widget2;
@@ -457,7 +420,7 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
void ghb_sanitize_audio_tracks(signal_user_data_t *ud)
{
int ii;
- GhbValue *alist = get_audio_list(ud->settings);
+ GhbValue *alist = ghb_get_job_audio_list(ud->settings);
int count = ghb_array_len(alist);
for (ii = 0; ii < count; ii++)
@@ -574,7 +537,7 @@ ghb_get_user_audio_lang(GhbValue *settings, const hb_title_t *title, gint track)
GhbValue *audio_list, *asettings;
const gchar *lang;
- audio_list = get_audio_list(settings);
+ audio_list = ghb_get_job_audio_list(settings);
if (ghb_array_len(audio_list) <= track)
return "und";
asettings = ghb_array_get(audio_list, track);
@@ -735,7 +698,7 @@ audio_get_selected_settings(signal_user_data_t *ud, int *index)
// find audio settings
if (row < 0) return NULL;
- audio_list = get_audio_list(ud->settings);
+ audio_list = ghb_get_job_audio_list(ud->settings);
if (row >= ghb_array_len(audio_list))
return NULL;
@@ -921,7 +884,7 @@ ghb_audio_list_refresh_selected(signal_user_data_t *ud)
gtk_tree_path_free(tp);
if (row < 0) return;
- audio_list = get_audio_list(ud->settings);
+ audio_list = ghb_get_job_audio_list(ud->settings);
if (row >= ghb_array_len(audio_list))
return;
@@ -945,7 +908,7 @@ audio_refresh_list_ui(signal_user_data_t *ud)
tm_count = gtk_tree_model_iter_n_children(tm, NULL);
- audio_list = get_audio_list(ud->settings);
+ audio_list = ghb_get_job_audio_list(ud->settings);
count = ghb_array_len(audio_list);
if (count != tm_count)
{
@@ -1187,7 +1150,7 @@ audio_passthru_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_widget_to_setting(ud->settings, widget);
copy_mask = ghb_create_copy_mask(ud->settings);
- audio = get_audio_settings(ud->settings);
+ audio = ghb_get_job_audio_settings(ud->settings);
ghb_dict_set(audio, "CopyMask", copy_mask);
ghb_clear_presets_selection(ud);
}
@@ -1281,7 +1244,7 @@ ghb_clear_audio_list_settings(GhbValue *settings)
GhbValue *audio_list;
g_debug("clear_audio_list_settings ()");
- audio_list = get_audio_list(settings);
+ audio_list = ghb_get_job_audio_list(settings);
ghb_array_reset(audio_list);
}
@@ -1375,7 +1338,7 @@ audio_list_selection_changed_cb(GtkTreeSelection *ts, signal_user_data_t *ud)
gtk_tree_path_free(tp);
if (row < 0) return;
- audio_list = get_audio_list(ud->settings);
+ audio_list = ghb_get_job_audio_list(ud->settings);
if (row >= 0 && row < ghb_array_len(audio_list))
asettings = ghb_array_get(audio_list, row);
}
@@ -1393,7 +1356,7 @@ audio_add_to_settings(GhbValue *settings, GhbValue *asettings)
title_id = ghb_dict_get_int(settings, "title");
title = ghb_lookup_title(title_id, &titleindex);
- audio_list = get_audio_list(settings);
+ audio_list = ghb_get_job_audio_list(settings);
int track = ghb_dict_get_int(asettings, "Track");
aconfig = ghb_get_audio_info(title, track);
@@ -1420,8 +1383,8 @@ audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
title = ghb_lookup_title(title_id, &titleindex);
// Back up settings in case we need to revert.
- audio_dict = get_audio_settings(ud->settings);
- backup = ghb_value_dup(get_audio_list(ud->settings));
+ audio_dict = ghb_get_job_audio_settings(ud->settings);
+ backup = ghb_value_dup(ghb_get_job_audio_list(ud->settings));
GhbValue *pref_audio = ghb_dict_get_value(ud->settings, "AudioList");
asettings = audio_select_and_add_track(title, ud->settings, pref_audio,
"und", 0, 0);
@@ -1508,9 +1471,9 @@ audio_edit_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
gtk_tree_selection_select_iter(ts, &ti);
- audio_dict = get_audio_settings(ud->settings);
+ audio_dict = ghb_get_job_audio_settings(ud->settings);
// Back up settings in case we need to revert.
- backup = ghb_value_dup(get_audio_list(ud->settings));
+ backup = ghb_value_dup(ghb_get_job_audio_list(ud->settings));
// Pop up the edit dialog
GtkResponseType response;
@@ -1567,7 +1530,7 @@ audio_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
gtk_tree_selection_select_iter(ts, &nextIter);
}
- audio_list = get_audio_list(ud->settings);
+ audio_list = ghb_get_job_audio_list(ud->settings);
// Get the row number
indices = gtk_tree_path_get_indices (tp);
@@ -2215,7 +2178,7 @@ G_MODULE_EXPORT void
audio_fallback_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
ghb_widget_to_setting(ud->settings, widget);
- GhbValue *audio = get_audio_settings(ud->settings);
+ GhbValue *audio = ghb_get_job_audio_settings(ud->settings);
ghb_dict_set(audio, "FallbackEncoder", ghb_value_dup(
ghb_dict_get(ud->settings, "AudioEncoderFallback")));
audio_def_set_all_limits(ud);
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c
index 5c5160880..dc2db46b1 100644
--- a/gtk/src/callbacks.c
+++ b/gtk/src/callbacks.c
@@ -78,7 +78,6 @@
#include "x264handler.h"
static void load_all_titles(signal_user_data_t *ud, int titleindex);
-static void update_chapter_list_settings(GhbValue *settings);
static GList* dvd_device_list();
static void prune_logs(signal_user_data_t *ud);
void ghb_notify_done(signal_user_data_t *ud);
@@ -1137,24 +1136,6 @@ check_chapter_markers(signal_user_data_t *ud)
}
}
-#if 0
-void
-show_settings(GhbValue *settings)
-{
- GhbDictIter iter;
- const gchar *key;
- GhbValue *gval;
-
- iter = ghb_dict_iter_init(settings);
- while (ghb_dict_iter_next(settings, &iter, &key, &gval))
- {
- char *str = ghb_value_get_string_xform(gval);
- printf("show key %s val %s\n", key, str);
- g_free(str);
- }
-}
-#endif
-
void
ghb_load_settings(signal_user_data_t * ud)
{
@@ -1531,6 +1512,8 @@ dest_dir_set_cb(GtkFileChooserButton *dest_chooser, signal_user_data_t *ud)
dest_dir = ghb_dict_get_string(ud->settings, "dest_dir");
dest = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dest_dir, dest_file);
ghb_dict_set_string(ud->settings, "destination", dest);
+ GhbValue *dest_dict = ghb_get_job_dest_settings(ud->settings);
+ ghb_dict_set_string(dest_dict, "File", dest);
g_free(dest);
update_default_destination = TRUE;
}
@@ -1550,6 +1533,8 @@ dest_file_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
dest_dir = ghb_dict_get_string(ud->settings, "dest_dir");
dest = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dest_dir, dest_file);
ghb_dict_set_string(ud->settings, "destination", dest);
+ GhbValue *dest_dict = ghb_get_job_dest_settings(ud->settings);
+ ghb_dict_set_string(dest_dict, "File", dest);
g_free(dest);
update_default_destination = TRUE;
}
@@ -1808,6 +1793,16 @@ ghb_update_title_info(signal_user_data_t *ud)
update_scale_info(ud);
}
+static void update_meta(GhbValue *settings, const char *name, const char *val)
+{
+ GhbValue *metadata = ghb_get_job_metadata_settings(settings);
+
+ if (val == NULL || val[0] == 0)
+ ghb_dict_remove(metadata, name);
+ else
+ ghb_dict_set_string(metadata, name, val);
+}
+
void
set_title_settings(signal_user_data_t *ud, GhbValue *settings)
{
@@ -1870,34 +1865,44 @@ set_title_settings(signal_user_data_t *ud, GhbValue *settings)
ghb_dict_set_int(settings, "angle_count", title->angle_count);
ghb_dict_set_string(settings, "MetaName", title->name);
+ update_meta(settings, "Name", title->name);
if (title->metadata)
{
if (title->metadata->name)
{
ghb_dict_set_string(settings, "MetaName",
title->metadata->name);
+ update_meta(settings, "Name", title->metadata->name);
}
ghb_dict_set_string(settings, "MetaArtist",
title->metadata->artist);
+ update_meta(settings, "Artist", title->metadata->artist);
ghb_dict_set_string(settings, "MetaReleaseDate",
title->metadata->release_date);
+ update_meta(settings, "ReleaseDate", title->metadata->release_date);
ghb_dict_set_string(settings, "MetaComment",
title->metadata->comment);
+ update_meta(settings, "Comment", title->metadata->comment);
if (!title->metadata->name && title->metadata->album)
{
ghb_dict_set_string(settings, "MetaName",
title->metadata->album);
+ update_meta(settings, "Name", title->metadata->album);
}
ghb_dict_set_string(settings, "MetaAlbumArtist",
title->metadata->album_artist);
+ update_meta(settings, "AlbumArtist", title->metadata->album_artist);
ghb_dict_set_string(settings, "MetaGenre",
title->metadata->genre);
+ update_meta(settings, "Genre", title->metadata->genre);
ghb_dict_set_string(settings, "MetaDescription",
title->metadata->description);
+ update_meta(settings, "Description", title->metadata->description);
ghb_dict_set_string(settings, "MetaLongDescription",
title->metadata->long_description);
+ update_meta(settings, "LongDescription",
+ title->metadata->long_description);
}
- update_chapter_list_settings(settings);
}
set_destination_settings(ud, settings);
@@ -1910,6 +1915,8 @@ set_title_settings(signal_user_data_t *ud, GhbValue *settings)
dest_dir = ghb_dict_get_string(settings, "dest_dir");
dest = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dest_dir, dest_file);
ghb_dict_set_string(settings, "destination", dest);
+ GhbValue *dest_dict = ghb_get_job_dest_settings(ud->settings);
+ ghb_dict_set_string(dest_dict, "File", dest);
g_free(dest);
ghb_dict_set_int(settings, "preview_frame", 2);
@@ -2009,11 +2016,17 @@ ptop_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
const hb_title_t * title;
gboolean numeric = TRUE;
GtkSpinButton *spin;
+ GhbValue *range;
ghb_widget_to_setting(ud->settings, widget);
ghb_check_dependency(ud, widget, NULL);
ghb_live_reset(ud);
+ // Update type in Job
+ range = ghb_get_job_range_settings(ud->settings);
+ ghb_dict_set_string(range, "Type",
+ ghb_dict_get_string(ud->settings, "PtoPType"));
+
title_id = ghb_dict_get_int(ud->settings, "title");
title = ghb_lookup_title(title_id, &titleindex);
if (title == NULL)
@@ -2079,18 +2092,98 @@ setting_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_live_reset(ud);
}
+G_MODULE_EXPORT void
+title_angle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ ghb_widget_to_setting(ud->settings, widget);
+ ghb_check_dependency(ud, widget, NULL);
+ ghb_clear_presets_selection(ud);
+ ghb_live_reset(ud);
+
+ GhbValue *source = ghb_get_job_source_settings(ud->settings);
+ ghb_dict_set_int(source, "Angle", ghb_dict_get_int(ud->settings, "angle"));
+}
+
G_MODULE_EXPORT gboolean
meta_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
signal_user_data_t *ud)
{
+ const char *val;
+
ghb_widget_to_setting(ud->settings, widget);
+ val = ghb_dict_get_string(ud->settings, "MetaLongDescription");
+ update_meta(ud->settings, "LongDescription", val);
return FALSE;
}
G_MODULE_EXPORT void
-meta_setting_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+meta_name_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ const char *val;
+
+ ghb_widget_to_setting(ud->settings, widget);
+ val = ghb_dict_get_string(ud->settings, "MetaName");
+ update_meta(ud->settings, "Name", val);
+}
+
+G_MODULE_EXPORT void
+meta_artist_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ const char *val;
+
+ ghb_widget_to_setting(ud->settings, widget);
+ val = ghb_dict_get_string(ud->settings, "MetaArtist");
+ update_meta(ud->settings, "Artist", val);
+}
+
+G_MODULE_EXPORT void
+meta_album_artist_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ const char *val;
+
+ ghb_widget_to_setting(ud->settings, widget);
+ val = ghb_dict_get_string(ud->settings, "MetaAlbumArtist");
+ update_meta(ud->settings, "AlbumArtist", val);
+}
+
+G_MODULE_EXPORT void
+meta_release_date_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ const char *val;
+
+ ghb_widget_to_setting(ud->settings, widget);
+ val = ghb_dict_get_string(ud->settings, "MetaReleaseDate");
+ update_meta(ud->settings, "ReleaseDate", val);
+}
+
+G_MODULE_EXPORT void
+meta_comment_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
+ const char *val;
+
ghb_widget_to_setting(ud->settings, widget);
+ val = ghb_dict_get_string(ud->settings, "MetaComment");
+ update_meta(ud->settings, "Comment", val);
+}
+
+G_MODULE_EXPORT void
+meta_genre_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ const char *val;
+
+ ghb_widget_to_setting(ud->settings, widget);
+ val = ghb_dict_get_string(ud->settings, "MetaGenre");
+ update_meta(ud->settings, "Genre", val);
+}
+
+G_MODULE_EXPORT void
+meta_description_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ const char *val;
+
+ ghb_widget_to_setting(ud->settings, widget);
+ val = ghb_dict_get_string(ud->settings, "MetaDescription");
+ update_meta(ud->settings, "Description", val);
}
G_MODULE_EXPORT void
@@ -2108,6 +2201,16 @@ chapter_markers_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_check_dependency(ud, widget, NULL);
ghb_clear_presets_selection(ud);
ghb_live_reset(ud);
+
+ GhbValue *dest;
+ int start, end;
+ bool markers;
+ dest = ghb_get_job_dest_settings(ud->settings);
+ markers = ghb_dict_get_bool(ud->settings, "ChapterMarkers");
+ start = ghb_dict_get_int(ud->settings, "start_point");
+ end = ghb_dict_get_int(ud->settings, "end_point");
+ markers &= (end > start);
+ ghb_dict_set_bool(dest, "ChapterMarkers", markers);
}
G_MODULE_EXPORT void
@@ -2165,17 +2268,6 @@ vquality_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
set_destination(ud);
}
-G_MODULE_EXPORT void
-http_opt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
- ghb_widget_to_setting(ud->settings, widget);
- ghb_check_dependency(ud, widget, NULL);
- ghb_clear_presets_selection(ud);
- ghb_live_reset(ud);
- // AC3 is not allowed when Web optimized
- ghb_grey_combo_options (ud);
-}
-
G_MODULE_EXPORT gboolean
ptop_input_cb(GtkWidget *widget, gdouble *val, signal_user_data_t *ud)
{
@@ -2228,82 +2320,128 @@ ptop_output_cb(GtkWidget *widget, signal_user_data_t *ud)
G_MODULE_EXPORT void
start_point_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- gint start, end;
+ int64_t start, end;
ghb_widget_to_setting(ud->settings, widget);
+
+ GhbValue *dest = ghb_get_job_dest_settings(ud->settings);
+ GhbValue *range = ghb_get_job_range_settings(ud->settings);
if (ghb_settings_combo_int(ud->settings, "PtoPType") == 0)
{
start = ghb_dict_get_int(ud->settings, "start_point");
- end = ghb_dict_get_int(ud->settings, "end_point");
+ end = ghb_dict_get_int(ud->settings, "end_point");
if (start > end)
+ {
ghb_ui_update(ud, "end_point", ghb_int_value(start));
+ end = start;
+ }
ghb_check_dependency(ud, widget, NULL);
if (check_name_template(ud, "{chapters}"))
set_destination(ud);
widget = GHB_WIDGET (ud->builder, "ChapterMarkers");
- // End may have been changed above, get it again
- end = ghb_dict_get_int(ud->settings, "end_point");
gtk_widget_set_sensitive(widget, end > start);
update_title_duration(ud);
+
+ bool markers;
+ markers = ghb_dict_get_int(ud->settings, "ChapterMarkers");
+ markers &= (end > start);
+ ghb_dict_set_bool(dest, "ChapterMarkers", markers);
+ ghb_dict_set_int(range, "Start", start);
+ ghb_dict_set_int(range, "End", end);
}
else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 1)
{
start = ghb_dict_get_int(ud->settings, "start_point");
- end = ghb_dict_get_int(ud->settings, "end_point");
+ end = ghb_dict_get_int(ud->settings, "end_point");
if (start >= end)
+ {
ghb_ui_update(ud, "end_point", ghb_int_value(start+1));
+ end = start + 1;
+ }
ghb_check_dependency(ud, widget, NULL);
update_title_duration(ud);
+
+ ghb_dict_set_int(range, "Start", start * 90000);
+ ghb_dict_set_int(range, "End", (end - start) * 90000);
}
else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 2)
{
start = ghb_dict_get_int(ud->settings, "start_point");
- end = ghb_dict_get_int(ud->settings, "end_point");
+ end = ghb_dict_get_int(ud->settings, "end_point");
if (start > end)
+ {
ghb_ui_update(ud, "end_point", ghb_int_value(start));
+ end = start;
+ }
ghb_check_dependency(ud, widget, NULL);
update_title_duration(ud);
+
+ ghb_dict_set_int(range, "Start", start - 1);
+ ghb_dict_set_int(range, "End", end - 1 - start);
}
}
G_MODULE_EXPORT void
end_point_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- gint start, end;
+ int64_t start, end;
ghb_widget_to_setting(ud->settings, widget);
+
+ GhbValue *dest = ghb_get_job_dest_settings(ud->settings);
+ GhbValue *range = ghb_get_job_range_settings(ud->settings);
if (ghb_settings_combo_int(ud->settings, "PtoPType") == 0)
{
start = ghb_dict_get_int(ud->settings, "start_point");
- end = ghb_dict_get_int(ud->settings, "end_point");
+ end = ghb_dict_get_int(ud->settings, "end_point");
if (start > end)
+ {
ghb_ui_update(ud, "start_point", ghb_int_value(end));
+ start = end;
+ }
ghb_check_dependency(ud, widget, NULL);
if (check_name_template(ud, "{chapters}"))
set_destination(ud);
widget = GHB_WIDGET (ud->builder, "ChapterMarkers");
- // Start may have been changed above, get it again
- start = ghb_dict_get_int(ud->settings, "start_point");
gtk_widget_set_sensitive(widget, end > start);
update_title_duration(ud);
+
+ bool markers;
+ markers = ghb_dict_get_int(ud->settings, "ChapterMarkers");
+ markers &= (end > start);
+ ghb_dict_set_bool(dest, "ChapterMarkers", markers);
+ ghb_dict_set_int(range, "Start", start);
+ ghb_dict_set_int(range, "End", end);
}
else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 1)
{
start = ghb_dict_get_int(ud->settings, "start_point");
- end = ghb_dict_get_int(ud->settings, "end_point");
+ end = ghb_dict_get_int(ud->settings, "end_point");
if (start >= end)
+ {
ghb_ui_update(ud, "start_point", ghb_int_value(end-1));
+ start = end - 1;
+ }
ghb_check_dependency(ud, widget, NULL);
update_title_duration(ud);
+
+ ghb_dict_set_int(range, "Start", start * 90000);
+ ghb_dict_set_int(range, "End", (end - start) * 90000);
}
else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 2)
{
start = ghb_dict_get_int(ud->settings, "start_point");
- end = ghb_dict_get_int(ud->settings, "end_point");
+ end = ghb_dict_get_int(ud->settings, "end_point");
if (start > end)
+ {
ghb_ui_update(ud, "start_point", ghb_int_value(end));
+ start = end;
+ }
ghb_check_dependency(ud, widget, NULL);
update_title_duration(ud);
+
+ ghb_dict_set_int(range, "Start", start - 1);
+ ghb_dict_set_int(range, "End", end - 1 - start);
}
}
@@ -2777,7 +2915,7 @@ submit_job(signal_user_data_t *ud, GhbValue *settings)
ghb_dict_set_int(settings, "job_unique_id", unique_id);
ghb_dict_set_int(settings, "job_status", GHB_QUEUE_RUNNING);
start_new_log(ud, settings);
- ghb_add_job(settings, unique_id);
+ ghb_add_job(ghb_queue_handle(), settings, unique_id);
ghb_start_queue();
// Start queue activity spinner
@@ -3699,7 +3837,7 @@ chapter_refresh_list_row_ui(
// Update row with settings data
g_debug("Updating chapter row ui");
- chapter = ghb_value_get_string(ghb_array_get(chapter_list, index));
+ chapter = ghb_dict_get_string(ghb_array_get(chapter_list, index), "Name");
duration = ghb_get_chapter_duration(title, index) / 90000;
break_duration(duration, &hh, &mm, &ss);
s_duration = g_strdup_printf("%02d:%02d:%02d", hh, mm, ss);
@@ -3746,7 +3884,7 @@ chapter_refresh_list_ui(signal_user_data_t *ud)
title_id = ghb_dict_get_int(ud->settings, "title");
title = ghb_lookup_title(title_id, &titleindex);
- chapter_list = ghb_dict_get_value(ud->settings, "chapter_list");
+ chapter_list = ghb_get_job_chapter_list(ud->settings);
count = ghb_array_len(chapter_list);
if (count != tm_count)
{
@@ -3769,21 +3907,6 @@ ghb_chapter_list_refresh_all(signal_user_data_t *ud)
chapter_refresh_list_ui(ud);
}
-static void
-update_chapter_list_settings(GhbValue *settings)
-{
- GhbValue *chapters;
- gint title_id, titleindex;
- const hb_title_t *title;
-
- g_debug("update_chapter_list_settings ()");
- title_id = ghb_dict_get_int(settings, "title");
- title = ghb_lookup_title(title_id, &titleindex);
- chapters = ghb_get_chapters(title);
- if (chapters)
- ghb_dict_set(settings, "chapter_list", chapters);
-}
-
static gint chapter_edit_key = 0;
G_MODULE_EXPORT gboolean
@@ -3829,9 +3952,9 @@ chapter_edited_cb(
const GhbValue *chapters;
GhbValue *chapter;
- chapters = ghb_dict_get_value(ud->settings, "chapter_list");
+ chapters = ghb_get_job_chapter_list(ud->settings);
chapter = ghb_array_get(chapters, index-1);
- ghb_string_value_set(chapter, text);
+ ghb_dict_set_string(chapter, "Name", text);
if ((chapter_edit_key == GDK_KEY_Return || chapter_edit_key == GDK_KEY_Down) &&
gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter))
{
diff --git a/gtk/src/ghb-3.12.ui b/gtk/src/ghb-3.12.ui
index 95cc6521d..e66881fad 100644
--- a/gtk/src/ghb-3.12.ui
+++ b/gtk/src/ghb-3.12.ui
@@ -1170,7 +1170,7 @@ This is often the feature title of a DVD.</property>
<property name="secondary_icon_activatable">False</property>
<property name="adjustment">adjustment27</property>
<property name="halign">end</property>
- <signal name="value-changed" handler="setting_widget_changed_cb" swapped="no"/>
+ <signal name="value-changed" handler="title_angle_changed_cb" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -1498,7 +1498,7 @@ This is often the feature title of a DVD.</property>
This allows a player to initiate playback before downloading the entire file.</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
- <signal name="toggled" handler="http_opt_changed_cb" swapped="no"/>
+ <signal name="toggled" handler="setting_widget_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">1</property>
@@ -6214,7 +6214,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_name_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">0</property>
@@ -6251,7 +6251,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_artist_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">1</property>
@@ -6288,7 +6288,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_album_artist_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">2</property>
@@ -6325,7 +6325,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_release_date_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">3</property>
@@ -6362,7 +6362,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_comment_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">4</property>
@@ -6399,7 +6399,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_genre_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">5</property>
@@ -6436,7 +6436,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_description_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 738075217..9a3cf537d 100644
--- a/gtk/src/ghb-3.14.ui
+++ b/gtk/src/ghb-3.14.ui
@@ -1171,7 +1171,7 @@ This is often the feature title of a DVD.</property>
<property name="secondary_icon_activatable">False</property>
<property name="adjustment">adjustment27</property>
<property name="halign">end</property>
- <signal name="value-changed" handler="setting_widget_changed_cb" swapped="no"/>
+ <signal name="value-changed" handler="title_angle_changed_cb" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -1499,7 +1499,7 @@ This is often the feature title of a DVD.</property>
This allows a player to initiate playback before downloading the entire file.</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
- <signal name="toggled" handler="http_opt_changed_cb" swapped="no"/>
+ <signal name="toggled" handler="setting_widget_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">1</property>
@@ -6218,7 +6218,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_name_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">0</property>
@@ -6255,7 +6255,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_artist_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">1</property>
@@ -6292,7 +6292,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_album_artist_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">2</property>
@@ -6329,7 +6329,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_release_date_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">3</property>
@@ -6366,7 +6366,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_comment_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">4</property>
@@ -6403,7 +6403,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_genre_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">5</property>
@@ -6440,7 +6440,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_description_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 413d1637a..add5b6c6c 100644
--- a/gtk/src/ghb.ui
+++ b/gtk/src/ghb.ui
@@ -1170,7 +1170,7 @@ This is often the feature title of a DVD.</property>
<property name="secondary_icon_activatable">False</property>
<property name="adjustment">adjustment27</property>
<property name="halign">end</property>
- <signal name="value-changed" handler="setting_widget_changed_cb" swapped="no"/>
+ <signal name="value-changed" handler="title_angle_changed_cb" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -1498,7 +1498,7 @@ This is often the feature title of a DVD.</property>
This allows a player to initiate playback before downloading the entire file.</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
- <signal name="toggled" handler="http_opt_changed_cb" swapped="no"/>
+ <signal name="toggled" handler="setting_widget_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">1</property>
@@ -6214,7 +6214,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_name_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">0</property>
@@ -6251,7 +6251,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_artist_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">1</property>
@@ -6288,7 +6288,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_album_artist_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">2</property>
@@ -6325,7 +6325,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_release_date_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">3</property>
@@ -6362,7 +6362,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_comment_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">4</property>
@@ -6399,7 +6399,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_genre_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">5</property>
@@ -6436,7 +6436,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="truncate_multiline">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="meta_setting_widget_changed_cb" swapped="no"/>
+ <signal name="changed" handler="meta_description_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">6</property>
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index 90d25f3ee..29c0493b4 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -36,6 +36,7 @@
#include "videohandler.h"
#include "x264handler.h"
#include "preview.h"
+#include "presets.h"
#include "values.h"
#include "lang.h"
#include "jansson.h"
@@ -2365,33 +2366,6 @@ ghb_find_subtitle_track(const hb_title_t * title, const gchar * lang, int start)
return -1;
}
-#if 0
-static void
-generic_opts_set(GtkBuilder *builder, const gchar *name, combo_opts_t *opts)
-{
- GtkTreeIter iter;
- GtkListStore *store;
- gint ii;
-
- g_debug("generic_opts_set ()\n");
- if (name == NULL || opts == NULL) return;
- GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
- store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
- gtk_list_store_clear(store);
- for (ii = 0; ii < opts->count; ii++)
- {
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- 0, gettext(opts->map[ii].option),
- 1, TRUE,
- 2, opts->map[ii].shortOpt,
- 3, opts->map[ii].ivalue,
- 4, opts->map[ii].svalue,
- -1);
- }
-}
-#endif
-
static void
small_opts_set(GtkBuilder *builder, const gchar *name, combo_opts_t *opts)
{
@@ -2666,80 +2640,6 @@ ghb_build_advanced_opts_string(GhbValue *settings)
}
}
-void ghb_set_video_encoder_opts(hb_dict_t *dict, GhbValue *js)
-{
- gint vcodec = ghb_settings_video_encoder_codec(js, "VideoEncoder");
- switch (vcodec)
- {
- case HB_VCODEC_X265:
- case HB_VCODEC_X264:
- {
- if (vcodec == HB_VCODEC_X264 &&
- ghb_dict_get_bool(js, "x264UseAdvancedOptions"))
- {
- const char *opts;
- opts = ghb_dict_get_string(js, "x264Option");
- hb_dict_set(dict, "Options", hb_value_string(opts));
- }
- else
- {
- const char *preset, *tune, *profile, *level, *opts;
- GString *str = g_string_new("");
- preset = ghb_dict_get_string(js, "VideoPreset");
- tune = ghb_dict_get_string(js, "VideoTune");
- profile = ghb_dict_get_string(js, "VideoProfile");
- level = ghb_dict_get_string(js, "VideoLevel");
- opts = ghb_dict_get_string(js, "VideoOptionExtra");
- char *tunes;
-
- g_string_append_printf(str, "%s", tune);
- if (vcodec == HB_VCODEC_X264)
- {
- if (ghb_dict_get_bool(js, "x264FastDecode"))
- {
- g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "fastdecode");
- }
- if (ghb_dict_get_bool(js, "x264ZeroLatency"))
- {
- g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "zerolatency");
- }
- }
- tunes = g_string_free(str, FALSE);
-
- if (preset != NULL)
- hb_dict_set(dict, "Preset", hb_value_string(preset));
- if (tunes != NULL && strcasecmp(tune, "none"))
- hb_dict_set(dict, "Tune", hb_value_string(tunes));
- if (profile != NULL && strcasecmp(profile, "auto"))
- hb_dict_set(dict, "Profile", hb_value_string(profile));
- if (level != NULL && strcasecmp(level, "auto"))
- hb_dict_set(dict, "Level", hb_value_string(level));
- if (opts != NULL)
- hb_dict_set(dict, "Options", hb_value_string(opts));
-
- g_free(tunes);
- }
- } break;
-
- case HB_VCODEC_FFMPEG_MPEG2:
- case HB_VCODEC_FFMPEG_MPEG4:
- case HB_VCODEC_FFMPEG_VP8:
- {
- const char *opts;
- opts = ghb_dict_get_string(js, "VideoOptionExtra");
- if (opts != NULL && opts[0])
- {
- hb_dict_set(dict, "Options", hb_value_string(opts));
- }
- } break;
-
- case HB_VCODEC_THEORA:
- default:
- {
- } break;
- }
-}
-
void
ghb_part_duration(const hb_title_t *title, gint sc, gint ec, gint *hh, gint *mm, gint *ss)
{
@@ -2805,36 +2705,6 @@ ghb_get_chapter_start(const hb_title_t *title, gint chap)
return start;
}
-GhbValue*
-ghb_get_chapters(const hb_title_t *title)
-{
- hb_chapter_t * chapter;
- gint count, ii;
- GhbValue *chapters = NULL;
-
- chapters = ghb_array_new();
-
- if (title == NULL) return chapters;
- count = hb_list_count( title->list_chapter );
- for (ii = 0; ii < count; ii++)
- {
- chapter = hb_list_item(title->list_chapter, ii);
- if (chapter == NULL) break;
- if (chapter->title == NULL || chapter->title[0] == 0)
- {
- gchar *str;
- str = g_strdup_printf (_("Chapter %2d"), ii+1);
- ghb_array_append(chapters, ghb_string_value_new(str));
- g_free(str);
- }
- else
- {
- ghb_array_append(chapters, ghb_string_value_new(chapter->title));
- }
- }
- return chapters;
-}
-
void
ghb_audio_bitrate_opts_filter(
GtkComboBox *combo,
@@ -3504,6 +3374,11 @@ ghb_set_scale_settings(GhbValue *settings, gint mode)
ghb_dict_set_int(settings, "PicturePARHeight", resultGeo.par.den);
ghb_dict_set_int(settings, "PictureDisplayWidth", disp_width);
ghb_dict_set_int(settings, "PictureDisplayHeight", resultGeo.height);
+
+ // Update Job PAR
+ GhbValue *par = ghb_get_job_par_settings(settings);
+ ghb_dict_set_int(par, "Num", resultGeo.par.num);
+ ghb_dict_set_int(par, "Den", resultGeo.par.den);
}
void
@@ -3780,7 +3655,7 @@ ghb_validate_subtitles(GhbValue *settings, GtkWindow *parent)
gint count, ii, track;
gboolean burned, one_burned = FALSE;
- slist = ghb_get_subtitle_list(settings);
+ slist = ghb_get_job_subtitle_list(settings);
count = ghb_array_len(slist);
for (ii = 0; ii < count; ii++)
{
@@ -3859,7 +3734,7 @@ ghb_validate_audio(GhbValue *settings, GtkWindow *parent)
const GhbValue *audio_list;
gint count, ii;
- audio_list = ghb_get_audio_list(settings);
+ audio_list = ghb_get_job_audio_list(settings);
count = ghb_array_len(audio_list);
for (ii = 0; ii < count; ii++)
{
@@ -3964,513 +3839,21 @@ ghb_validate_audio(GhbValue *settings, GtkWindow *parent)
return TRUE;
}
-static void
-add_job(hb_handle_t *h, GhbValue *js, gint unique_id)
+void
+ghb_add_job(hb_handle_t *h, GhbValue *js, gint unique_id)
{
- hb_dict_t * dict;
- json_error_t error;
-
- // Assumes that the UI has reduced geometry settings to only the
- // necessary PAR value
-
- const char *mux_name;
- const hb_container_t *mux;
- int mux_id;
-
- mux_name = ghb_dict_get_string(js, "FileFormat");
- mux = ghb_lookup_container_by_name(mux_name);
-
- mux_id = mux->format;
-
- int p_to_p = -1, range_seek_points = 0, chapter_markers = 0;
- int64_t range_start = 0, range_end = 0;
- range_start = ghb_dict_get_int(js, "start_frame") + 1;
- const char *range_type = "chapter";
- if (range_start != 0)
- {
- range_type = "preview";
- GhbValue *prefs = ghb_dict_get_value(js, "Preferences");
- range_seek_points = ghb_dict_get_int(prefs, "preview_count");
- range_end = ghb_dict_get_int(prefs, "live_duration") * 90000LL;
- }
- else
- {
- chapter_markers = ghb_dict_get_bool(js, "ChapterMarkers");
- p_to_p = ghb_settings_combo_int(js, "PtoPType");
- switch (p_to_p)
- {
- default:
- case 0: // Chapter range
- {
- range_type = "chapter";
- range_start = ghb_dict_get_int(js, "start_point");
- range_end = ghb_dict_get_int(js, "end_point");
- if (range_start == range_end)
- chapter_markers = 0;
- } break;
- case 1: // PTS range
- {
- double start, end;
- range_type = "time";
- start = ghb_dict_get_double(js, "start_point");
- end = ghb_dict_get_double(js, "end_point");
- range_start = (int64_t)start * 90000;
- range_end = (int64_t)end * 90000 - range_start;
- } break;
- case 2: // Frame range
- {
- range_type = "frame";
- range_start = ghb_dict_get_int(js, "start_point") - 1;
- range_end = ghb_dict_get_int(js, "end_point") - 1 -
- range_start;
- } break;
- }
- }
-
- const char *path = ghb_dict_get_string(js, "source");
- int title_id = ghb_dict_get_int(js, "title");
-
- int angle = ghb_dict_get_int(js, "angle");
-
- hb_rational_t par;
- par.num = ghb_dict_get_int(js, "PicturePARWidth");
- par.den = ghb_dict_get_int(js, "PicturePARHeight");
-
- int vcodec, grayscale;
- vcodec = ghb_settings_video_encoder_codec(js, "VideoEncoder");
- grayscale = ghb_dict_get_bool(js, "VideoGrayScale");
-
- dict = json_pack_ex(&error, 0,
- "{"
- // SequenceID
- "s:o,"
- // Destination {Mux, ChapterMarkers, ChapterList}
- "s:{s:o, s:o, s[]},"
- // Source {Path, Title, Angle}
- "s:{s:o, s:o, s:o,},"
- // PAR {Num, Den}
- "s:{s:o, s:o},"
- // Video {Codec}
- "s:{s:o},"
- // Metadata
- "s:{},"
- // Filters {Grayscale, FilterList []}
- "s:{s:o, s:[]}"
- "}",
- "SequenceID", hb_value_int(unique_id),
- "Destination",
- "Mux", hb_value_int(mux_id),
- "ChapterMarkers", hb_value_bool(chapter_markers),
- "ChapterList",
- "Source",
- "Path", hb_value_string(path),
- "Title", hb_value_int(title_id),
- "Angle", hb_value_int(angle),
- "PAR",
- "Num", hb_value_int(par.num),
- "Den", hb_value_int(par.den),
- "Video",
- "Encoder", hb_value_int(vcodec),
- "Metadata",
- "Filters",
- "Grayscale", hb_value_bool(grayscale),
- "FilterList"
- );
- if (dict == NULL)
- {
- g_warning("json pack job failure: %s", error.text);
- return;
- }
- const char *dest = ghb_dict_get_string(js, "destination");
- hb_dict_t *dest_dict = hb_dict_get(dict, "Destination");
- if (dest != NULL)
- {
- hb_dict_set(dest_dict, "File", hb_value_string(dest));
- }
- if (mux_id & HB_MUX_MASK_MP4)
- {
- int mp4_optimize, ipod_atom = 0;
- mp4_optimize = ghb_dict_get_bool(js, "Mp4HttpOptimize");
- if (vcodec == HB_VCODEC_X264)
- {
- ipod_atom = ghb_dict_get_bool(js, "Mp4iPodCompatible");
- }
- hb_dict_t *mp4_dict;
- mp4_dict = json_pack_ex(&error, 0, "{s:o, s:o}",
- "Mp4Optimize", hb_value_bool(mp4_optimize),
- "IpodAtom", hb_value_bool(ipod_atom));
- if (mp4_dict == NULL)
- {
- g_warning("json pack mp4 failure: %s", error.text);
- return;
- }
- hb_dict_set(dest_dict, "Mp4Options", mp4_dict);
- }
- hb_dict_t *source_dict = hb_dict_get(dict, "Source");
- if (range_start || range_end)
- {
- hb_dict_t *range_dict = hb_dict_init();
- hb_dict_set(range_dict, "Type", hb_value_string(range_type));
- if (range_start)
- hb_dict_set(range_dict, "Start", hb_value_int(range_start));
- if (range_end)
- hb_dict_set(range_dict, "End", hb_value_int(range_end));
- if (range_seek_points)
- {
- hb_dict_set(range_dict, "SeekPoints",
- hb_value_int(range_seek_points));
- }
- hb_dict_set(source_dict, "Range", range_dict);
- }
-
- hb_dict_t *video_dict = hb_dict_get(dict, "Video");
- if (ghb_dict_get_bool(js, "vquality_type_constant"))
- {
- double vquality = ghb_dict_get_double(js, "VideoQualitySlider");
- hb_dict_set(video_dict, "Quality", hb_value_double(vquality));
- }
- else if (ghb_dict_get_bool(js, "vquality_type_bitrate"))
- {
- int vbitrate, twopass, fastfirstpass;
- vbitrate = ghb_dict_get_int(js, "VideoAvgBitrate");
- twopass = ghb_dict_get_bool(js, "VideoTwoPass");
- fastfirstpass = ghb_dict_get_bool(js, "VideoTurboTwoPass");
- hb_dict_set(video_dict, "Bitrate", hb_value_int(vbitrate));
- hb_dict_set(video_dict, "TwoPass", hb_value_bool(twopass));
- hb_dict_set(video_dict, "Turbo", hb_value_bool(fastfirstpass));
- }
- ghb_set_video_encoder_opts(video_dict, js);
+ GhbValue *job;
+ char *json_job;
- hb_dict_t *meta_dict = hb_dict_get(dict, "Metadata");
- const char * meta;
-
- meta = ghb_dict_get_string(js, "MetaName");
- if (meta && *meta)
- {
- hb_dict_set(meta_dict, "Name", hb_value_string(meta));
- }
- meta = ghb_dict_get_string(js, "MetaArtist");
- if (meta && *meta)
- {
- hb_dict_set(meta_dict, "Artist", hb_value_string(meta));
- }
- meta = ghb_dict_get_string(js, "MetaAlbumArtist");
- if (meta && *meta)
- {
- hb_dict_set(meta_dict, "AlbumArtist", hb_value_string(meta));
- }
- meta = ghb_dict_get_string(js, "MetaReleaseDate");
- if (meta && *meta)
- {
- hb_dict_set(meta_dict, "ReleaseDate", hb_value_string(meta));
- }
- meta = ghb_dict_get_string(js, "MetaComment");
- if (meta && *meta)
- {
- hb_dict_set(meta_dict, "Comment", hb_value_string(meta));
- }
- meta = ghb_dict_get_string(js, "MetaGenre");
- if (meta && *meta)
- {
- hb_dict_set(meta_dict, "Genre", hb_value_string(meta));
- }
- meta = ghb_dict_get_string(js, "MetaDescription");
- if (meta && *meta)
- {
- hb_dict_set(meta_dict, "Description", hb_value_string(meta));
- }
- meta = ghb_dict_get_string(js, "MetaLongDescription");
- if (meta && *meta)
- {
- hb_dict_set(meta_dict, "LongDescription", hb_value_string(meta));
- }
-
- // process chapter list
- if (chapter_markers)
- {
- hb_value_array_t *chapter_list = hb_dict_get(dest_dict, "ChapterList");
- GhbValue *chapters;
- GhbValue *chapter;
- gint chap;
- gint count;
-
- chapters = ghb_dict_get_value(js, "chapter_list");
- count = ghb_array_len(chapters);
- for(chap = 0; chap < count; chap++)
- {
- hb_dict_t *chapter_dict;
- gchar *name;
-
- name = NULL;
- chapter = ghb_array_get(chapters, chap);
- name = ghb_value_get_string_xform(chapter);
- if (name == NULL)
- {
- name = g_strdup_printf (_("Chapter %2d"), chap+1);
- }
- chapter_dict = json_pack_ex(&error, 0, "{s:o}",
- "Name", hb_value_string(name));
- if (chapter_dict == NULL)
- {
- g_warning("json pack chapter failure: %s", error.text);
- return;
- }
- hb_value_array_append(chapter_list, chapter_dict);
- g_free(name);
- }
- }
-
- // Create filter list
- hb_dict_t *filters_dict = hb_dict_get(dict, "Filters");
- hb_value_array_t *filter_list = hb_dict_get(filters_dict, "FilterList");
- hb_dict_t *filter_dict;
- char *filter_str;
-
- // Crop scale filter
- int width, height, crop[4];
- width = ghb_dict_get_int(js, "scale_width");
- height = ghb_dict_get_int(js, "scale_height");
-
- crop[0] = ghb_dict_get_int(js, "PictureTopCrop");
- crop[1] = ghb_dict_get_int(js, "PictureBottomCrop");
- crop[2] = ghb_dict_get_int(js, "PictureLeftCrop");
- crop[3] = ghb_dict_get_int(js, "PictureRightCrop");
-
- filter_str = g_strdup_printf("%d:%d:%d:%d:%d:%d",
- width, height, crop[0], crop[1], crop[2], crop[3]);
- filter_dict = json_pack_ex(&error, 0, "{s:o, s:o}",
- "ID", hb_value_int(HB_FILTER_CROP_SCALE),
- "Settings", hb_value_string(filter_str));
- if (filter_dict == NULL)
- {
- g_warning("json pack scale filter failure: %s", error.text);
- return;
- }
- hb_value_array_append(filter_list, filter_dict);
- g_free(filter_str);
-
- // detelecine filter
- gint detel = ghb_settings_combo_int(js, "PictureDetelecine");
- if (detel)
- {
- const char *filter_str = NULL;
- if (detel != 1)
- {
- if (detel_opts.map[detel].svalue != NULL)
- filter_str = detel_opts.map[detel].svalue;
- }
- else
- {
- filter_str = ghb_dict_get_string(js, "PictureDetelecineCustom");
- }
- filter_dict = json_pack_ex(&error, 0, "{s:o}",
- "ID", hb_value_int(HB_FILTER_DETELECINE));
- if (filter_dict == NULL)
- {
- g_warning("json pack detelecine filter failure: %s", error.text);
- return;
- }
- if (filter_str != NULL)
- {
- hb_dict_set(filter_dict, "Settings", hb_value_string(filter_str));
- }
- hb_value_array_append(filter_list, filter_dict);
- }
-
- // Decomb filter
- gboolean decomb_deint;
- gint decomb, deint;
- decomb_deint = ghb_dict_get_bool(js, "PictureDecombDeinterlace");
- decomb = ghb_settings_combo_int(js, "PictureDecomb");
- deint = ghb_settings_combo_int(js, "PictureDeinterlace");
- if (decomb_deint && decomb)
- {
- const char *filter_str = NULL;
- if (decomb != 1)
- {
- if (decomb_opts.map[decomb].svalue != NULL)
- filter_str = decomb_opts.map[decomb].svalue;
- }
- else
- {
- filter_str = ghb_dict_get_string(js, "PictureDecombCustom");
- }
- filter_dict = json_pack_ex(&error, 0, "{s:o}",
- "ID", hb_value_int(HB_FILTER_DECOMB));
- if (filter_dict == NULL)
- {
- g_warning("json pack decomb filter failure: %s", error.text);
- return;
- }
- if (filter_str != NULL)
- {
- hb_dict_set(filter_dict, "Settings", hb_value_string(filter_str));
- }
- hb_value_array_append(filter_list, filter_dict);
- }
-
- // Deinterlace filter
- if ( !decomb_deint && deint )
- {
- const char *filter_str = NULL;
- if (deint != 1)
- {
- if (deint_opts.map[deint].svalue != NULL)
- filter_str = deint_opts.map[deint].svalue;
- }
- else
- {
- filter_str = ghb_dict_get_string(js, "PictureDeinterlaceCustom");
- }
- filter_dict = json_pack_ex(&error, 0, "{s:o}",
- "ID", hb_value_int(HB_FILTER_DEINTERLACE));
- if (filter_dict == NULL)
- {
- g_warning("json pack deinterlace filter failure: %s", error.text);
- return;
- }
- if (filter_str != NULL)
- {
- hb_dict_set(filter_dict, "Settings", hb_value_string(filter_str));
- }
- hb_value_array_append(filter_list, filter_dict);
- }
-
- // Denoise filter
- if (strcmp(ghb_dict_get_string(js, "PictureDenoiseFilter"), "off"))
- {
- int filter_id = HB_FILTER_HQDN3D;
- if (!strcmp(ghb_dict_get_string(js, "PictureDenoiseFilter"), "nlmeans"))
- filter_id = HB_FILTER_NLMEANS;
-
- if (!strcmp(ghb_dict_get_string(js, "PictureDenoisePreset"), "custom"))
- {
- const char *filter_str;
- filter_str = ghb_dict_get_string(js, "PictureDenoiseCustom");
- filter_dict = json_pack_ex(&error, 0, "{s:o}",
- "ID", hb_value_int(filter_id));
- if (filter_dict == NULL)
- {
- g_warning("json pack denoise filter failure: %s", error.text);
- return;
- }
- if (filter_str != NULL)
- {
- hb_dict_set(filter_dict, "Settings", hb_value_string(filter_str));
- }
- hb_value_array_append(filter_list, filter_dict);
- }
- else
- {
- const char *preset, *tune;
- preset = ghb_dict_get_string(js, "PictureDenoisePreset");
- tune = ghb_dict_get_string(js, "PictureDenoiseTune");
- filter_str = hb_generate_filter_settings(filter_id, preset, tune);
- if (filter_str == NULL)
- {
- g_warning("Invalid %s preset %s and/or tune %s",
- filter_id == HB_FILTER_HQDN3D ? "HQDN3D" : "NLMeans",
- preset, tune);
- }
- filter_dict = json_pack_ex(&error, 0, "{s:o}",
- "ID", hb_value_int(filter_id));
- if (filter_dict == NULL)
- {
- g_warning("json pack denoise filter failure: %s", error.text);
- return;
- }
- if (filter_str != NULL)
- {
- hb_dict_set(filter_dict, "Settings", hb_value_string(filter_str));
- }
- hb_value_array_append(filter_list, filter_dict);
- g_free(filter_str);
- }
- }
-
- // Deblock filter
- gint deblock = ghb_dict_get_int(js, "PictureDeblock");
- if( deblock >= 5 )
- {
- filter_str = g_strdup_printf("%d", deblock);
- filter_dict = json_pack_ex(&error, 0, "{s:o}",
- "ID", hb_value_int(HB_FILTER_DEBLOCK));
- if (filter_dict == NULL)
- {
- g_warning("json pack deblock filter failure: %s", error.text);
- return;
- }
- if (filter_str != NULL)
- {
- hb_dict_set(filter_dict, "Settings", hb_value_string(filter_str));
- }
- hb_value_array_append(filter_list, filter_dict);
- g_free(filter_str);
- }
-
- // VFR filter
- gint vrate_den = ghb_settings_video_framerate_rate(js, "VideoFramerate");
- gint cfr;
- if (ghb_dict_get_bool(js, "VideoFrameratePFR"))
- cfr = 2;
- else if (ghb_dict_get_bool(js, "VideoFramerateCFR"))
- cfr = 1;
- else
- cfr = 0;
-
- // x264 zero latency requires CFR encode
- if (ghb_dict_get_bool(js, "x264ZeroLatency"))
- {
- cfr = 1;
- ghb_log("zerolatency x264 tune selected, forcing constant framerate");
- }
-
- if (vrate_den == 0)
- {
- filter_str = g_strdup_printf("%d", cfr);
- }
- else
- {
- filter_str = g_strdup_printf("%d:%d:%d", cfr, 27000000, vrate_den);
- }
- filter_dict = json_pack_ex(&error, 0, "{s:o, s:o}",
- "ID", hb_value_int(HB_FILTER_VFR),
- "Settings", hb_value_string(filter_str));
- if (filter_dict == NULL)
- {
- g_warning("json pack vfr filter failure: %s", error.text);
- return;
- }
- hb_value_array_append(filter_list, filter_dict);
- g_free(filter_str);
-
- // Create audio list
- hb_dict_t *audios_dict = ghb_get_audio_settings(js);
- hb_dict_set(dict, "Audio", ghb_value_dup(audios_dict));
-
- GhbValue *subtitle_dict = ghb_get_subtitle_settings(js);
- hb_dict_set(dict, "Subtitle", ghb_value_dup(subtitle_dict));
-
- char *json_job = hb_value_get_json(dict);
- hb_value_free(&dict);
+ job = ghb_dict_get(js, "Job");
+ ghb_dict_set_int(job, "SequenceID", unique_id);
+ json_job = hb_value_get_json(job);
hb_add_json(h, json_job);
free(json_job);
}
void
-ghb_add_job(GhbValue *js, gint unique_id)
-{
- add_job(h_queue, js, unique_id);
-}
-
-void
-ghb_add_live_job(GhbValue *js, gint unique_id)
-{
- add_job(h_live, js, unique_id);
-}
-
-void
ghb_remove_job(gint unique_id)
{
hb_job_t * job;
diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h
index 84033cf65..940a4340a 100644
--- a/gtk/src/hb-backend.h
+++ b/gtk/src/hb-backend.h
@@ -90,13 +90,12 @@ float ghb_vquality_default(signal_user_data_t *ud);
void ghb_combo_init(signal_user_data_t *ud);
void ghb_backend_init(gint debug);
void ghb_backend_close(void);
-void ghb_add_job(GhbValue *js, gint unique_id);
+void ghb_add_job(hb_handle_t *h, GhbValue *js, gint unique_id);
void ghb_remove_job(gint unique_id);
void ghb_start_queue(void);
void ghb_stop_queue(void);
void ghb_pause_queue(void);
-void ghb_add_live_job(GhbValue *js, gint unique_id);
void ghb_start_live_encode();
void ghb_stop_live_encode();
@@ -117,7 +116,6 @@ void ghb_par_init(signal_user_data_t *ud);
void ghb_set_scale(signal_user_data_t *ud, gint mode);
void ghb_set_scale_settings(GhbValue *settings, gint mode);
void ghb_picture_settings_deps(signal_user_data_t *ud);
-GhbValue* ghb_get_chapters(const hb_title_t *title);
gint64 ghb_get_chapter_duration(const hb_title_t *title, gint chap);
gint64 ghb_get_chapter_start(const hb_title_t *title, gint chap);
void ghb_part_duration(
diff --git a/gtk/src/presets.c b/gtk/src/presets.c
index 9af423803..d75f9f9ef 100644
--- a/gtk/src/presets.c
+++ b/gtk/src/presets.c
@@ -289,14 +289,7 @@ ghb_preset_to_settings(GhbValue *settings, GhbValue *preset)
vqtype = ghb_dict_get_int(settings, "VideoQualityType");
// "Use max" or "strict anamorphic" imply autoscale
- if (uses_pic == 2)
- {
- ghb_dict_set_bool(settings, "autoscale", TRUE);
- }
- else if (uses_pic == 1)
- {
- ghb_dict_set_bool(settings, "autoscale", FALSE);
- }
+ ghb_dict_set_bool(settings, "autoscale", uses_pic == 2);
// VideoQualityType/0/1/2 - vquality_type_/target/bitrate/constant
// *note: target is no longer used
@@ -1358,8 +1351,8 @@ GhbValue* ghb_create_copy_mask(GhbValue *settings)
}
// Translate internal values to preset key, value pairs
-static GhbValue*
-settings_to_preset(GhbValue *settings)
+GhbValue*
+ghb_settings_to_preset(GhbValue *settings)
{
GhbValue *preset = ghb_value_dup(settings);
@@ -1446,26 +1439,28 @@ settings_to_preset(GhbValue *settings)
ghb_dict_remove(preset, "VideoLevel");
ghb_dict_remove(preset, "VideoOptionExtra");
}
+
+ GString *str = g_string_new("");
+ const char *sep = "";
const char *tune = ghb_dict_get_string(preset, "VideoTune");
- if (tune != NULL)
+ if (tune != NULL && strcasecmp(tune, "none"))
{
- GString *str = g_string_new("");
- char *tunes;
-
g_string_append_printf(str, "%s", tune);
- if (ghb_dict_get_bool(preset, "x264FastDecode"))
- {
- g_string_append_printf(str, ",%s", "fastdecode");
- }
- if (ghb_dict_get_bool(preset, "x264ZeroLatency"))
- {
- g_string_append_printf(str, ",%s", "zerolatency");
- }
- tunes = g_string_free(str, FALSE);
- ghb_dict_set_string(preset, "VideoTune", tunes);
-
- g_free(tunes);
+ sep = ",";
+ }
+ if (ghb_dict_get_bool(preset, "x264FastDecode"))
+ {
+ g_string_append_printf(str, "%s%s", sep, "fastdecode");
+ sep = ",";
+ }
+ if (ghb_dict_get_bool(preset, "x264ZeroLatency"))
+ {
+ g_string_append_printf(str, "%s%s", sep, "zerolatency");
}
+ char *tunes;
+ tunes = g_string_free(str, FALSE);
+ ghb_dict_set_string(preset, "VideoTune", tunes);
+ g_free(tunes);
GhbValue *in_val, *out_val;
@@ -1563,7 +1558,7 @@ settings_save(signal_user_data_t *ud, hb_preset_index_t *path, const char *name)
replace = TRUE;
}
}
- dict = settings_to_preset(ud->settings);
+ dict = ghb_settings_to_preset(ud->settings);
ghb_dict_set_string(dict, "PresetName", name);
if (replace)
{
diff --git a/gtk/src/presets.h b/gtk/src/presets.h
index 9cb546ca7..3041c9d57 100644
--- a/gtk/src/presets.h
+++ b/gtk/src/presets.h
@@ -45,5 +45,6 @@ void ghb_prefs_to_settings(GhbValue *settings);
GhbValue* ghb_read_settings_file(const gchar *path);
void ghb_write_settings_file(const gchar *path, GhbValue *dict);
GhbValue* ghb_create_copy_mask(GhbValue *settings);
+GhbValue* ghb_settings_to_preset(GhbValue *settings);
#endif // _GHB_PRESETS_H_
diff --git a/gtk/src/preview.c b/gtk/src/preview.c
index 9f79486bf..b4bcc4fe2 100644
--- a/gtk/src/preview.c
+++ b/gtk/src/preview.c
@@ -39,6 +39,7 @@
#include "hb-backend.h"
#include "preview.h"
#include "values.h"
+#include "queuehandler.h"
#include "hb.h"
#define PREVIEW_STATE_IMAGE 0
@@ -759,14 +760,25 @@ live_preview_start_cb(GtkWidget *xwidget, signal_user_data_t *ud)
else
{
GhbValue *js;
+ GhbValue *range, *dest;
ud->preview->encode_frame = frame;
js = ghb_value_dup(ud->settings);
- ghb_dict_set_string(js, "destination", name);
- ghb_dict_set_int(js, "start_frame", ud->preview->frame);
+
+ ghb_finalize_job(js);
+ range = ghb_get_job_range_settings(js);
+ dest = ghb_get_job_dest_settings(js);
+
+ ghb_dict_set_string(dest, "File", name);
+ ghb_dict_set_string(range, "Type", "preview");
+ ghb_dict_set_int(range, "Start", ud->preview->frame);
+ ghb_dict_set_int(range, "End",
+ ghb_dict_get_int(ud->prefs, "live_duration") * 90000);
+ ghb_dict_set_int(range, "SeekPoints",
+ ghb_dict_get_int(ud->prefs, "preview_count"));
+
ud->preview->live_id = 0;
- ghb_dict_set(js, "Preferences", ghb_value_dup(ud->prefs));
- ghb_add_live_job(js, ud->preview->live_id);
+ ghb_add_job(ghb_live_handle(), js, ud->preview->live_id);
ghb_start_live_encode();
ghb_value_free(&js);
}
diff --git a/gtk/src/queuehandler.c b/gtk/src/queuehandler.c
index 8e8a2b7ee..960b3a619 100644
--- a/gtk/src/queuehandler.c
+++ b/gtk/src/queuehandler.c
@@ -535,7 +535,7 @@ add_to_queue_list(signal_user_data_t *ud, GhbValue *settings, GtkTreeIter *piter
gint count, ii;
const GhbValue *audio_list;
- audio_list = ghb_get_audio_list(settings);
+ audio_list = ghb_get_job_audio_list(settings);
count = ghb_array_len(audio_list);
if (count == 1)
{
@@ -601,7 +601,7 @@ add_to_queue_list(signal_user_data_t *ud, GhbValue *settings, GtkTreeIter *piter
const GhbValue *sub_dict, *sub_list, *sub_search;
gboolean search;
- sub_dict = ghb_get_subtitle_settings(settings);
+ sub_dict = ghb_get_job_subtitle_settings(settings);
sub_list = ghb_dict_get(sub_dict, "SubtitleList");
sub_search = ghb_dict_get(sub_dict, "Search");
search = ghb_dict_get_bool(sub_search, "Enable");
@@ -1040,6 +1040,43 @@ validate_settings(signal_user_data_t *ud, GhbValue *settings, gint batch)
return TRUE;
}
+void ghb_finalize_job(GhbValue *settings)
+{
+ GhbValue *preset, *job;
+
+ preset = ghb_settings_to_preset(settings);
+ job = ghb_dict_get(settings, "Job");
+
+ // Apply selected preset settings
+ hb_preset_apply_mux(preset, job);
+ hb_preset_apply_video(preset, job);
+ hb_preset_apply_filters(preset, job);
+
+ // Add scale filter since the above does not
+ GhbValue *filter_list, *filter_dict;
+ int width, height, crop[4];
+ char *filter_str;
+
+ filter_list = ghb_get_job_filter_list(settings);
+ width = ghb_dict_get_int(settings, "scale_width");
+ height = ghb_dict_get_int(settings, "scale_height");
+
+ crop[0] = ghb_dict_get_int(settings, "PictureTopCrop");
+ crop[1] = ghb_dict_get_int(settings, "PictureBottomCrop");
+ crop[2] = ghb_dict_get_int(settings, "PictureLeftCrop");
+ crop[3] = ghb_dict_get_int(settings, "PictureRightCrop");
+
+ filter_str = g_strdup_printf("%d:%d:%d:%d:%d:%d",
+ width, height, crop[0], crop[1], crop[2], crop[3]);
+ filter_dict = ghb_dict_new();
+ ghb_dict_set_int(filter_dict, "ID", HB_FILTER_CROP_SCALE);
+ ghb_dict_set_string(filter_dict, "Settings", filter_str);
+ hb_value_array_append(filter_list, filter_dict);
+ g_free(filter_str);
+
+ ghb_value_free(&preset);
+}
+
static gboolean
queue_add(signal_user_data_t *ud, GhbValue *settings, gint batch)
{
@@ -1053,6 +1090,8 @@ queue_add(signal_user_data_t *ud, GhbValue *settings, gint batch)
if (ud->queue == NULL)
ud->queue = ghb_array_new();
+ ghb_finalize_job(settings);
+
// Copy current prefs into settings
// The job should run with the preferences that existed
// when the job was added to the queue.
@@ -1417,6 +1456,8 @@ title_dest_file_cb(GtkWidget *widget, signal_user_data_t *ud)
dest_dir = ghb_dict_get_string(settings, "dest_dir");
dest = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dest_dir, dest_file);
ghb_dict_set_string(settings, "destination", dest);
+ GhbValue *dest_dict = ghb_get_job_dest_settings(settings);
+ ghb_dict_set_string(dest_dict, "File", dest);
// Check if changing the destination file name resolves
// a file name conflict. Enable selection if so.
@@ -1451,6 +1492,8 @@ title_dest_dir_cb(GtkWidget *widget, signal_user_data_t *ud)
dest_file = ghb_dict_get_string(settings, "dest_file");
dest = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dest_dir, dest_file);
ghb_dict_set_string(settings, "destination", dest);
+ GhbValue *dest_dict = ghb_get_job_dest_settings(settings);
+ ghb_dict_set_string(dest_dict, "File", dest);
// Check if changing the destination file name resolves
// a file name conflict. Enable selection if so.
diff --git a/gtk/src/queuehandler.h b/gtk/src/queuehandler.h
index 2b1a18850..9ca8907f5 100644
--- a/gtk/src/queuehandler.h
+++ b/gtk/src/queuehandler.h
@@ -31,5 +31,6 @@
void ghb_queue_buttons_grey(signal_user_data_t *ud);
gboolean ghb_reload_queue(signal_user_data_t *ud);
void ghb_queue_remove_row(signal_user_data_t *ud, int row);
+void ghb_finalize_job(GhbValue *settings);
#endif // _QUEUEHANDLER_H_
diff --git a/gtk/src/settings.c b/gtk/src/settings.c
index 4fde72e7b..5a1ed6fb2 100644
--- a/gtk/src/settings.c
+++ b/gtk/src/settings.c
@@ -61,6 +61,187 @@ GhbValue *ghb_get_job_settings(GhbValue *settings)
return job;
}
+GhbValue* ghb_get_job_dest_settings(GhbValue *settings)
+{
+ GhbValue *job = ghb_get_job_settings(settings);
+ GhbValue *dest = ghb_dict_get(job, "Destination");
+ if (dest == NULL)
+ {
+ dest = ghb_dict_new();
+ ghb_dict_set(job, "Destination", dest);
+ }
+ return dest;
+}
+
+GhbValue* ghb_get_job_chapter_list(GhbValue *settings)
+{
+ GhbValue *dest = ghb_get_job_dest_settings(settings);
+ GhbValue *chapters = ghb_dict_get(dest, "ChapterList");
+ if (chapters == NULL)
+ {
+ chapters = ghb_array_new();
+ ghb_dict_set(dest, "ChapterList", chapters);
+ }
+ return chapters;
+}
+
+GhbValue* ghb_get_job_mp4_settings(GhbValue *settings)
+{
+ GhbValue *dest = ghb_get_job_dest_settings(settings);
+ GhbValue *mp4 = ghb_dict_get(dest, "Mp4Options");
+ if (mp4 == NULL)
+ {
+ mp4 = ghb_dict_new();
+ ghb_dict_set(dest, "Mp4Options", mp4);
+ }
+ return mp4;
+}
+
+GhbValue* ghb_get_job_source_settings(GhbValue *settings)
+{
+ GhbValue *job = ghb_get_job_settings(settings);
+ GhbValue *source = ghb_dict_get(job, "Source");
+ if (source == NULL)
+ {
+ source = ghb_dict_new();
+ ghb_dict_set(job, "Source", source);
+ }
+ return source;
+}
+
+GhbValue* ghb_get_job_range_settings(GhbValue *settings)
+{
+ GhbValue *source = ghb_get_job_source_settings(settings);
+ GhbValue *range = ghb_dict_get(source, "Range");
+ if (range == NULL)
+ {
+ range = ghb_dict_new();
+ ghb_dict_set(source, "Range", range);
+ }
+ return range;
+}
+
+GhbValue* ghb_get_job_par_settings(GhbValue *settings)
+{
+ GhbValue *job = ghb_get_job_settings(settings);
+ GhbValue *par = ghb_dict_get(job, "PAR");
+ if (par == NULL)
+ {
+ par = ghb_dict_new();
+ ghb_dict_set(job, "PAR", par);
+ }
+ return par;
+}
+
+GhbValue* ghb_get_job_video_settings(GhbValue *settings)
+{
+ GhbValue *job = ghb_get_job_settings(settings);
+ GhbValue *video = ghb_dict_get(job, "Video");
+ if (video == NULL)
+ {
+ video = ghb_dict_new();
+ ghb_dict_set(job, "Video", video);
+ }
+ return video;
+}
+
+GhbValue *ghb_get_job_audio_settings(GhbValue *settings)
+{
+ GhbValue *job = ghb_get_job_settings(settings);
+ GhbValue *audio = ghb_dict_get(job, "Audio");
+ if (audio == NULL)
+ {
+ audio = ghb_dict_new();
+ ghb_dict_set(job, "Audio", audio);
+ }
+ return audio;
+}
+
+GhbValue *ghb_get_job_audio_list(GhbValue *settings)
+{
+ GhbValue *audio_dict = ghb_get_job_audio_settings(settings);
+ GhbValue *audio_list = ghb_dict_get(audio_dict, "AudioList");
+ if (audio_list == NULL)
+ {
+ audio_list = ghb_array_new();
+ ghb_dict_set(audio_dict, "AudioList", audio_list);
+ }
+ return audio_list;
+}
+
+GhbValue *ghb_get_job_subtitle_settings(GhbValue *settings)
+{
+ GhbValue *job = ghb_get_job_settings(settings);
+ GhbValue *sub = ghb_dict_get(job, "Subtitle");
+ if (sub == NULL)
+ {
+ sub = ghb_dict_new();
+ ghb_dict_set(job, "Subtitle", sub);
+ }
+ return sub;
+}
+
+GhbValue *ghb_get_job_subtitle_list(GhbValue *settings)
+{
+ GhbValue *sub_dict = ghb_get_job_subtitle_settings(settings);
+ GhbValue *sub_list = ghb_dict_get(sub_dict, "SubtitleList");
+ if (sub_list == NULL)
+ {
+ sub_list = ghb_array_new();
+ ghb_dict_set(sub_dict, "SubtitleList", sub_list);
+ }
+ return sub_list;
+}
+
+GhbValue *ghb_get_job_subtitle_search(GhbValue *settings)
+{
+ GhbValue *sub_dict = ghb_get_job_subtitle_settings(settings);
+ GhbValue *sub_search = ghb_dict_get(sub_dict, "Search");
+ if (sub_search == NULL)
+ {
+ sub_search = ghb_dict_new();
+ ghb_dict_set(sub_dict, "Search", sub_search);
+ ghb_dict_set_bool(sub_search, "Enable", 0);
+ }
+ return sub_search;
+}
+
+GhbValue* ghb_get_job_metadata_settings(GhbValue *settings)
+{
+ GhbValue *job = ghb_get_job_settings(settings);
+ GhbValue *meta = ghb_dict_get(job, "Metadata");
+ if (meta == NULL)
+ {
+ meta = ghb_dict_new();
+ ghb_dict_set(job, "Metadata", meta);
+ }
+ return meta;
+}
+
+GhbValue* ghb_get_job_filter_settings(GhbValue *settings)
+{
+ GhbValue *job = ghb_get_job_settings(settings);
+ GhbValue *filter = ghb_dict_get(job, "Filters");
+ if (filter == NULL)
+ {
+ filter = ghb_dict_new();
+ ghb_dict_set(job, "Filters", filter);
+ }
+ return filter;
+}
+
+GhbValue* ghb_get_job_filter_list(GhbValue *settings)
+{
+ GhbValue *filter = ghb_get_job_filter_settings(settings);
+ GhbValue *list = ghb_dict_get(filter, "FilterList");
+ if (list == NULL)
+ {
+ list = ghb_dict_new();
+ ghb_dict_set(filter, "FilterList", list);
+ }
+ return list;
+}
+
// Map widget names to setting keys
// Widgets that map to settings have names
// of this format: s_<setting key>
diff --git a/gtk/src/settings.h b/gtk/src/settings.h
index c60d547f4..cffb04350 100644
--- a/gtk/src/settings.h
+++ b/gtk/src/settings.h
@@ -80,6 +80,23 @@ enum
GHB_QUEUE_DONE,
};
+GhbValue *ghb_get_job_settings(GhbValue *settings);
+GhbValue* ghb_get_job_source_settings(GhbValue *settings);
+GhbValue* ghb_get_job_range_settings(GhbValue *settings);
+GhbValue* ghb_get_job_par_settings(GhbValue *settings);
+GhbValue* ghb_get_job_dest_settings(GhbValue *settings);
+GhbValue* ghb_get_job_video_settings(GhbValue *settings);
+GhbValue* ghb_get_job_metadata_settings(GhbValue *settings);
+GhbValue* ghb_get_job_chapter_list(GhbValue *settings);
+GhbValue* ghb_get_job_mp4_settings(GhbValue *settings);
+GhbValue *ghb_get_job_audio_settings(GhbValue *settings);
+GhbValue *ghb_get_job_audio_list(GhbValue *settings);
+GhbValue *ghb_get_job_subtitle_settings(GhbValue *settings);
+GhbValue *ghb_get_job_subtitle_list(GhbValue *settings);
+GhbValue *ghb_get_job_subtitle_search(GhbValue *settings);
+GhbValue* ghb_get_job_filter_settings(GhbValue *settings);
+GhbValue* ghb_get_job_filter_list(GhbValue *settings);
+
void ghb_settings_copy(
GhbValue *settings, const gchar *key, const GhbValue *value);
gint ghb_settings_combo_int(const GhbValue *settings, const gchar *key);
diff --git a/gtk/src/subtitlehandler.c b/gtk/src/subtitlehandler.c
index a5e837a9d..e2cde7dc4 100644
--- a/gtk/src/subtitlehandler.c
+++ b/gtk/src/subtitlehandler.c
@@ -33,57 +33,6 @@ static void add_to_subtitle_list_ui(signal_user_data_t *ud, GhbValue *settings);
static void clear_subtitle_list_settings(GhbValue *settings);
static void clear_subtitle_list_ui(GtkBuilder *builder);
-static GhbValue *get_sub_settings(GhbValue *settings)
-{
- GhbValue *sub, *job;
- job = ghb_get_job_settings(settings);
- sub = ghb_dict_get(job, "Subtitle");
- if (sub == NULL)
- {
- sub = ghb_dict_new();
- ghb_dict_set(job, "Subtitle", sub);
- }
- return sub;
-}
-
-GhbValue *ghb_get_subtitle_settings(GhbValue *settings)
-{
- return get_sub_settings(settings);
-}
-
-
-static GhbValue *get_sub_list(GhbValue *settings)
-{
- GhbValue *sub_dict, *sub_list = NULL;
- sub_dict = get_sub_settings(settings);
- sub_list = ghb_dict_get(sub_dict, "SubtitleList");
- if (sub_list == NULL)
- {
- sub_list = ghb_array_new();
- ghb_dict_set(sub_dict, "SubtitleList", sub_list);
- }
- return sub_list;
-}
-
-GhbValue *ghb_get_subtitle_list(GhbValue *settings)
-{
- return get_sub_list(settings);
-}
-
-static GhbValue *get_sub_search(GhbValue *settings)
-{
- GhbValue *sub_dict, *sub_search = NULL;
- sub_dict = get_sub_settings(settings);
- sub_search = ghb_dict_get(sub_dict, "Search");
- if (sub_search == NULL)
- {
- sub_search = ghb_dict_new();
- ghb_dict_set(sub_dict, "Search", sub_search);
- ghb_dict_set_bool(sub_search, "Enable", 0);
- }
- return sub_search;
-}
-
static int get_sub_source(GhbValue *settings, GhbValue *subsettings)
{
if (ghb_dict_get(subsettings, "SRT") != NULL)
@@ -218,8 +167,8 @@ subtitle_refresh_list_ui_from_settings(signal_user_data_t *ud, GhbValue *setting
tm_count = gtk_tree_model_iter_n_children(tm, NULL);
- subtitle_list = get_sub_list(settings);
- subtitle_search = get_sub_search(settings);
+ subtitle_list = ghb_get_job_subtitle_list(settings);
+ subtitle_search = ghb_get_job_subtitle_search(settings);
search = ghb_dict_get_bool(subtitle_search, "Enable");
count = ghb_array_len(subtitle_list);
if (count + search != tm_count)
@@ -260,7 +209,7 @@ subtitle_exclusive_burn_settings(GhbValue *settings, gint index)
GhbValue *subsettings;
gint ii, count;
- subtitle_list = get_sub_list(settings);
+ subtitle_list = ghb_get_job_subtitle_list(settings);
count = ghb_array_len(subtitle_list);
for (ii = 0; ii < count; ii++)
{
@@ -286,7 +235,7 @@ subtitle_exclusive_default_settings(GhbValue *settings, gint index)
GhbValue *subtitle;
gint ii, count;
- subtitle_list = get_sub_list(settings);
+ subtitle_list = ghb_get_job_subtitle_list(settings);
count = ghb_array_len(subtitle_list);
for (ii = 0; ii < count; ii++)
{
@@ -325,7 +274,7 @@ subtitle_add_to_settings(GhbValue *settings, GhbValue *subsettings)
gboolean burn, forced, def;
gint source;
- subtitle_list = get_sub_list(settings);
+ subtitle_list = ghb_get_job_subtitle_list(settings);
if (subtitle_list == NULL)
{
g_warning("No subtitle list!");
@@ -625,7 +574,7 @@ subtitle_get_selected_settings(signal_user_data_t *ud, int *index)
row = indices[0];
gtk_tree_path_free(tp);
- subtitle_search = get_sub_search(ud->settings);
+ subtitle_search = ghb_get_job_subtitle_search(ud->settings);
search = ghb_dict_get_bool(subtitle_search, "Enable");
if (search)
{
@@ -638,7 +587,7 @@ subtitle_get_selected_settings(signal_user_data_t *ud, int *index)
row--;
}
- subtitle_list = get_sub_list(ud->settings);
+ subtitle_list = ghb_get_job_subtitle_list(ud->settings);
if (row < 0 || row >= ghb_array_len(subtitle_list))
return NULL;
@@ -984,8 +933,8 @@ clear_subtitle_list_settings(GhbValue *settings)
{
GhbValue *subtitle_list, *subtitle_search;
- subtitle_list = get_sub_list(settings);
- subtitle_search = get_sub_search(settings);
+ subtitle_list = ghb_get_job_subtitle_list(settings);
+ subtitle_search = ghb_get_job_subtitle_search(settings);
ghb_array_reset(subtitle_list);
ghb_dict_set_bool(subtitle_search, "Enable", 0);
}
@@ -1070,7 +1019,7 @@ static gboolean subtitle_is_one_burned(GhbValue *settings)
GhbValue *subtitle_list, *subsettings;
int count, ii;
- subtitle_list = get_sub_list(settings);
+ subtitle_list = ghb_get_job_subtitle_list(settings);
if (subtitle_list == NULL)
return FALSE;
@@ -1105,7 +1054,7 @@ subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
}
// Back up settings in case we need to revert.
- backup = ghb_value_dup(get_sub_settings(ud->settings));
+ backup = ghb_value_dup(ghb_get_job_subtitle_settings(ud->settings));
one_burned = subtitle_is_one_burned(ud->settings);
const char *mux_id;
@@ -1153,14 +1102,14 @@ subtitle_add_fas_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
GhbValue *subtitle_search, *backup;
- subtitle_search = get_sub_search(ud->settings);
+ subtitle_search = ghb_get_job_subtitle_search(ud->settings);
if (ghb_dict_get_bool(subtitle_search, "Enable"))
{
// Foreign audio search is already enabled
return;
}
- backup = ghb_value_dup(get_sub_settings(ud->settings));
+ backup = ghb_value_dup(ghb_get_job_subtitle_settings(ud->settings));
ghb_dict_set_bool(subtitle_search, "Enable", 1);
ghb_dict_set_bool(subtitle_search, "Forced", 1);
@@ -1256,7 +1205,7 @@ ghb_subtitle_prune(signal_user_data_t *ud)
gint ii;
gboolean one_burned = FALSE;
- subtitle_list = get_sub_list(ud->settings);
+ subtitle_list = ghb_get_job_subtitle_list(ud->settings);
if (subtitle_list == NULL)
return;
@@ -1555,7 +1504,7 @@ subtitle_edit_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
gtk_tree_selection_select_iter(ts, &ti);
// Back up settings in case we need to revert.
- backup = ghb_value_dup(get_sub_settings(ud->settings));
+ backup = ghb_value_dup(ghb_get_job_subtitle_settings(ud->settings));
// Pop up the edit dialog
GtkResponseType response;
@@ -1612,8 +1561,8 @@ subtitle_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *u
gtk_tree_selection_select_iter(ts, &nextIter);
}
- subtitle_search = get_sub_search(ud->settings);
- subtitle_list = get_sub_list(ud->settings);
+ subtitle_search = ghb_get_job_subtitle_search(ud->settings);
+ subtitle_list = ghb_get_job_subtitle_list(ud->settings);
// Get the row number
indices = gtk_tree_path_get_indices(tp);
diff --git a/libhb/preset.c b/libhb/preset.c
index 5035cacc9..4066b2bec 100644
--- a/libhb/preset.c
+++ b/libhb/preset.c
@@ -305,21 +305,24 @@ static int get_job_mux(hb_dict_t *job_dict)
return mux;
}
-static int get_audio_copy_mask(const hb_dict_t * preset)
+static hb_value_t* get_audio_copy_mask(const hb_dict_t * preset, int *mask)
{
- int mask = HB_ACODEC_PASS_FLAG;
+ int copy_mask;
+ hb_value_array_t *out_copy_mask, *in_copy_mask;
- hb_value_array_t *copy_mask_array = hb_dict_get(preset, "AudioCopyMask");
- if (copy_mask_array != NULL)
+ if (mask != NULL)
+ *mask = 0;
+ in_copy_mask = hb_dict_get(preset, "AudioCopyMask");
+ out_copy_mask = hb_value_array_init();
+ if (in_copy_mask != NULL)
{
- mask = HB_ACODEC_PASS_FLAG;
- int count = hb_value_array_len(copy_mask_array);
- int ii;
+ int count, ii;
+ count = hb_value_array_len(in_copy_mask);
for (ii = 0; ii < count; ii++)
{
int codec;
hb_value_t *value;
- value = hb_value_array_get(copy_mask_array, ii);
+ value = hb_value_array_get(in_copy_mask, ii);
if (hb_value_type(value) == HB_VALUE_TYPE_STRING)
{
char *tmp = NULL;
@@ -335,7 +338,8 @@ static int get_audio_copy_mask(const hb_dict_t * preset)
hb_error("Invalid audio codec in autopassthru copy mask (%s)", s);
hb_error("Codec name is invalid or can not be copied");
free(tmp);
- return HB_ACODEC_INVALID;
+ hb_value_free(&out_copy_mask);
+ return NULL;
}
free(tmp);
}
@@ -343,10 +347,14 @@ static int get_audio_copy_mask(const hb_dict_t * preset)
{
codec = hb_value_get_int(value);
}
- mask |= codec;
+ hb_value_array_append(out_copy_mask, hb_value_string(
+ hb_audio_encoder_get_short_name(codec)));
+ copy_mask |= codec;
}
}
- return mask;
+ if (mask != NULL)
+ *mask = copy_mask;
+ return out_copy_mask;
}
static hb_dict_t * source_audio_track_used(hb_dict_t *track_dict, int track)
@@ -535,7 +543,8 @@ static void add_audio_for_lang(hb_value_array_t *list, const hb_dict_t *preset,
}
// Save the encoder value before sanitizing. This value is
// useful to the frontends.
- hb_dict_set(audio_dict, "PresetEncoder", hb_value_int(out_codec));
+ hb_dict_set(audio_dict, "PresetEncoder",
+ hb_value_string(hb_audio_encoder_get_short_name(out_codec)));
hb_audio_config_t *aconfig;
aconfig = hb_list_audio_config_item(title->list_audio, track);
@@ -639,13 +648,14 @@ int hb_preset_job_add_audio(hb_handle_t *h, int title_index,
audio_dict = hb_dict_init();
hb_dict_set(job_dict, "Audio", audio_dict);
}
- int copy_mask = get_audio_copy_mask(preset);
- if (copy_mask == HB_ACODEC_INVALID)
+ int copy_mask;
+ hb_value_t *copy_mask_array = get_audio_copy_mask(preset, &copy_mask);
+ if (copy_mask_array == NULL)
{
return -1;
}
int fallback = 0;
- hb_dict_set(audio_dict, "CopyMask", hb_value_int(copy_mask));
+ hb_dict_set(audio_dict, "CopyMask", copy_mask_array);
hb_value_t *fallback_value = hb_dict_get(preset, "AudioEncoderFallback");
if (fallback_value != NULL)
{
@@ -1041,243 +1051,19 @@ static int get_video_framerate(hb_value_t *rate_value)
return rate;
}
-/**
- * Initialize an hb_job_t and return a hb_dict_t representation of the job.
- * This dict will have key/value pairs compatible with json jobs.
- * @param h - Pointer to hb_handle_t instance that contains the
- * specified title_index
- * @param title_index - Index of hb_title_t to use for job initialization.
- * Index comes from title->index or "Index" key
- * 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,
- const hb_dict_t *preset)
+int hb_preset_apply_filters(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)
- {
- hb_error("Invalid title index (%d)", title_index);
- return NULL;
- }
-
- hb_job_t *job = hb_job_init(title);
- hb_dict_t *job_dict = hb_job_to_dict(job);
- hb_job_close(&job);
-
- // Now apply preset settings to the job dict
-
- hb_value_t *mux_value = hb_dict_get(preset, "FileFormat");
- int mux;
- if (hb_value_type(mux_value) == HB_VALUE_TYPE_STRING)
- {
- mux = hb_container_get_from_name(hb_value_get_string(mux_value));
- if (mux == 0)
- mux = hb_container_get_from_extension(
- hb_value_get_string(mux_value));
- }
- else
- {
- mux = hb_value_get_int(mux_value);
- }
- hb_container_t *container = hb_container_get_from_format(mux);
- if (container == NULL)
- {
- char *str = hb_value_get_string_xform(mux_value);
- hb_error("Invalid container (%s)", str);
- free(str);
- goto fail;
- }
-
- hb_value_t *vcodec_value = hb_dict_get(preset, "VideoEncoder");
- int vcodec;
- if (hb_value_type(vcodec_value) == HB_VALUE_TYPE_STRING)
- {
- vcodec = hb_video_encoder_get_from_name(
- hb_value_get_string(vcodec_value));
- }
- else
- {
- vcodec = hb_value_get_int(vcodec_value);
- }
- hb_encoder_t *encoder = hb_video_encoder_get_from_codec(vcodec);
- if (encoder == NULL)
- {
- char *str = hb_value_get_string_xform(vcodec_value);
- hb_error("Invalid video encoder (%s)", str);
- free(str);
- goto fail;
- }
- if (!(encoder->muxers & mux))
- {
- hb_error("Incompatible video encoder (%s) for muxer (%s)",
- hb_video_encoder_get_name(vcodec),
- hb_container_get_name(mux));
- goto fail;
- }
-
- int chapters;
- chapters = hb_value_get_bool(hb_dict_get(preset, "ChapterMarkers"));
- if (hb_list_count(title->list_chapter) <= 1)
- chapters = 0;
-
- // Set "Destination" settings in job
- hb_dict_t *dest_dict = hb_dict_get(job_dict, "Destination");
- hb_dict_set(dest_dict, "ChapterMarkers", hb_value_bool(chapters));
- hb_dict_set(dest_dict, "Mux", hb_value_dup(mux_value));
- if (mux & HB_MUX_MASK_MP4)
- {
- hb_dict_t *mp4_dict = hb_dict_init();
- hb_dict_set(mp4_dict, "Mp4Optimize",
- hb_value_xform(hb_dict_get(preset, "Mp4HttpOptimize"),
- HB_VALUE_TYPE_BOOL));
- if (vcodec == HB_VCODEC_X264)
- {
- hb_dict_set(mp4_dict, "IpodAtom",
- hb_value_xform(hb_dict_get(preset, "Mp4iPodCompatible"),
- HB_VALUE_TYPE_BOOL));
- }
- hb_dict_set(dest_dict, "Mp4Options", mp4_dict);
- }
- dest_dict = NULL;
-
- // Calculate default job geometry settings
- hb_geometry_t srcGeo, resultGeo;
- hb_geometry_settings_t geo;
- int keep_aspect;
-
- srcGeo = title->geometry;
- if (!hb_value_get_bool(hb_dict_get(preset, "PictureAutoCrop")))
- {
- geo.crop[0] = hb_value_get_int(hb_dict_get(preset, "PictureTopCrop"));
- geo.crop[1] = hb_value_get_int(hb_dict_get(preset, "PictureBottomCrop"));
- geo.crop[2] = hb_value_get_int(hb_dict_get(preset, "PictureLeftCrop"));
- geo.crop[3] = hb_value_get_int(hb_dict_get(preset, "PictureRightCrop"));
- }
- else
- {
- memcpy(geo.crop, title->crop, sizeof(geo.crop));
- }
- geo.modulus = hb_value_get_int(hb_dict_get(preset, "PictureModulus"));
- if (geo.modulus < 2)
- geo.modulus = 2;
- if (hb_value_get_bool(hb_dict_get(preset, "PictureLooseCrop")))
- {
- // Crop a few extra pixels to avoid scaling to fit Modulus
- int extra1, extra2, crop_width, crop_height, width, height;
-
- crop_width = srcGeo.width - geo.crop[2] - geo.crop[3];
- crop_height = srcGeo.height - geo.crop[0] - geo.crop[1];
- width = MULTIPLE_MOD_DOWN(crop_width, geo.modulus);
- height = MULTIPLE_MOD_DOWN(crop_height, geo.modulus);
+ hb_value_t *filters_dict, *filter_list, *filter_dict;
+ char *filter_str;
- extra1 = EVEN((crop_height - height) / 2);
- extra2 = crop_height - height - extra1;
- geo.crop[0] += extra1;
- geo.crop[1] += extra2;
- extra1 = EVEN((crop_width - width) / 2);
- extra2 = crop_width - width - extra1;
- geo.crop[2] += extra1;
- geo.crop[3] += extra2;
- }
- hb_value_t *ana_mode_value = hb_dict_get(preset, "PicturePAR");
- if (hb_value_type(ana_mode_value) == HB_VALUE_TYPE_STRING)
- {
- const char *s = hb_value_get_string(ana_mode_value);
- if (!strcasecmp(s, "none"))
- geo.mode = 0;
- else if (!strcasecmp(s, "strict"))
- geo.mode = 1;
- else if (!strcasecmp(s, "custom"))
- geo.mode = 3;
- else // default loose
- geo.mode = 2;
- }
- else
- {
- geo.mode = hb_value_get_int(hb_dict_get(preset, "PicturePAR"));
- }
- keep_aspect = hb_value_get_bool(hb_dict_get(preset, "PictureKeepRatio"));
- if (geo.mode == HB_ANAMORPHIC_STRICT || geo.mode == HB_ANAMORPHIC_LOOSE)
- keep_aspect = 1;
- geo.keep = keep_aspect * HB_KEEP_DISPLAY_ASPECT;
- geo.itu_par = hb_value_get_bool(hb_dict_get(preset, "PictureItuPAR"));
- geo.maxWidth = hb_value_get_int(hb_dict_get(preset, "PictureWidth"));
- geo.maxHeight = hb_value_get_int(hb_dict_get(preset, "PictureHeight"));
- geo.geometry = title->geometry;
- int width = hb_value_get_int(hb_dict_get(preset, "PictureForceWidth"));
- int height = hb_value_get_int(hb_dict_get(preset, "PictureForceHeight"));
- if (width > 0)
- {
- geo.geometry.width = width;
- geo.keep |= HB_KEEP_WIDTH;
- }
- else
- {
- geo.geometry.width -= geo.crop[2] + geo.crop[3];
- }
- if (height > 0)
- {
- geo.geometry.height = height;
- geo.keep |= HB_KEEP_HEIGHT;
- }
- else
- {
- geo.geometry.height -= geo.crop[0] + geo.crop[1];
- }
- if (geo.mode == HB_ANAMORPHIC_CUSTOM && !keep_aspect)
- {
- int dar_width;
- dar_width = hb_value_get_int(hb_dict_get(preset, "PictureDARWidth"));
- if (dar_width > 0)
- {
- geo.geometry.par.num = dar_width;
- geo.geometry.par.num = geo.geometry.width;
- }
- else
- {
- geo.geometry.par.num =
- hb_value_get_int(hb_dict_get(preset, "PicturePARWidth"));
- geo.geometry.par.num =
- hb_value_get_int(hb_dict_get(preset, "PicturePARHeight"));
- }
- }
- hb_set_anamorphic_size2(&srcGeo, &geo, &resultGeo);
- hb_dict_t *par_dict = hb_dict_get(job_dict, "PAR");
- hb_dict_set(par_dict, "Num", hb_value_int(resultGeo.par.num));
- hb_dict_set(par_dict, "Den", hb_value_int(resultGeo.par.den));
- par_dict = NULL;
+ // Create new filters
+ filters_dict = hb_dict_init();
+ hb_dict_set(job_dict, "Filters", filters_dict);
+ filter_list = hb_value_array_init();
+ hb_dict_set(filters_dict, "FilterList", filter_list);
- // Filters
- hb_dict_t *filters_dict = hb_dict_get(job_dict, "Filters");
- if (filters_dict == NULL)
- {
- filters_dict = hb_dict_init();
- hb_dict_set(job_dict, "Filters", filters_dict);
- }
hb_dict_set(filters_dict, "Grayscale", hb_value_xform(
hb_dict_get(preset, "VideoGrayScale"), HB_VALUE_TYPE_BOOL));
- hb_value_array_t *filter_list = hb_dict_get(filters_dict, "FilterList");
- if (filter_list == NULL)
- {
- filter_list = hb_value_array_init();
- hb_dict_set(filters_dict, "FilterList", filter_list);
- }
-
- hb_dict_t *filter_dict;
- char *filter_str;
-
- // Setup scale filter
- filter_str = hb_strdup_printf("%d:%d:%d:%d:%d:%d",
- resultGeo.width, resultGeo.height,
- geo.crop[0], geo.crop[1],
- geo.crop[2], geo.crop[3]);
-
- filter_dict = hb_dict_init();
- hb_dict_set(filter_dict, "ID", hb_value_int(HB_FILTER_CROP_SCALE));
- hb_dict_set(filter_dict, "Settings", hb_value_string(filter_str));
- free(filter_str);
- hb_value_array_append(filter_list, filter_dict);
// Detelecine filter
hb_value_t *detel_val = hb_dict_get(preset, "PictureDetelecine");
@@ -1301,7 +1087,7 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
char *s = hb_value_get_string_xform(detel_val);
hb_error("Invalid detelecine filter settings (%s)", s);
free(s);
- goto fail;
+ return -1;
}
else if (filter_str != hb_filter_off)
{
@@ -1338,7 +1124,7 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
char *s = hb_value_get_string_xform(decomb_val);
hb_error("Invalid decomb filter settings (%s)", s);
free(s);
- goto fail;
+ return -1;
}
else if (filter_str != hb_filter_off)
{
@@ -1371,7 +1157,7 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
char *s = hb_value_get_string_xform(deint_val);
hb_error("Invalid deinterlace filter settings (%s)", s);
free(s);
- goto fail;
+ return -1;
}
else if (filter_str != hb_filter_off)
{
@@ -1414,7 +1200,7 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
denoise_preset,
denoise_tune ? "," : "",
denoise_tune ? denoise_tune : "");
- goto fail;
+ return -1;
}
else if (filter_str != hb_filter_off)
{
@@ -1438,7 +1224,7 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
if (filter_str == NULL)
{
hb_error("Invalid deblock filter settings (%s)", deblock);
- goto fail;
+ return -1;
}
else if (filter_str != hb_filter_off)
{
@@ -1461,7 +1247,7 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
if (filter_str == NULL)
{
hb_error("Invalid rotate filter settings (%s)", rotate);
- goto fail;
+ return -1;
}
else if (filter_str != hb_filter_off)
{
@@ -1481,7 +1267,7 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
char *str = hb_value_get_string_xform(fr_value);
hb_error("Invalid video framerate (%s)", str);
free(str);
- goto fail;
+ return -1;
}
int fr_mode;
@@ -1491,9 +1277,6 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
!strcasecmp(hb_value_get_string(fr_mode_value), "pfr") ? 2 : 0) :
hb_value_get_int(fr_mode_value);
- if (hb_value_get_bool(hb_dict_get(preset, "x264ZeroLatency")))
- fr_mode = 1;
-
if (vrate_den == 0)
filter_str = hb_strdup_printf("%d", fr_mode);
else
@@ -1505,73 +1288,79 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
hb_value_array_append(filter_list, filter_dict);
free(filter_str);
- // Video encoder settings
- hb_dict_t *video_dict = hb_dict_get(job_dict, "Video");
- hb_value_t *color_value;
+ return 0;
+}
+
+int hb_preset_apply_video(const hb_dict_t *preset, hb_dict_t *job_dict)
+{
+ hb_dict_t *dest_dict, *video_dict, *qsv;
+ hb_value_t *value, *vcodec_value, *color_value;
+ int mux, vcodec, vqtype;
+ hb_encoder_t *encoder;
+
+ dest_dict = hb_dict_get(job_dict, "Destination");
+ mux = hb_container_get_from_name(hb_value_get_string(
+ hb_dict_get(dest_dict, "Mux")));
+ vcodec_value = hb_dict_get(preset, "VideoEncoder");
+ if (hb_value_type(vcodec_value) == HB_VALUE_TYPE_STRING)
+ {
+ vcodec = hb_video_encoder_get_from_name(
+ hb_value_get_string(vcodec_value));
+ }
+ else
+ {
+ vcodec = hb_value_get_int(vcodec_value);
+ }
+ encoder = hb_video_encoder_get_from_codec(vcodec);
+ if (encoder == NULL)
+ {
+ char *str = hb_value_get_string_xform(vcodec_value);
+ hb_error("Invalid video encoder (%s)", str);
+ free(str);
+ return -1;
+ }
+ if (!(encoder->muxers & mux))
+ {
+ hb_error("Incompatible video encoder (%s) for muxer (%s)",
+ hb_video_encoder_get_name(vcodec),
+ hb_container_get_name(mux));
+ return -1;
+ }
+
+ video_dict = hb_dict_get(job_dict, "Video");
+ hb_dict_set(video_dict, "Encoder", hb_value_string(encoder->short_name));
+
if ((color_value = hb_dict_get(preset, "VideoColorMatrixCode")) != NULL)
hb_dict_set(video_dict, "ColorMatrixCode", hb_value_dup(color_value));
hb_dict_set(video_dict, "Encoder", hb_value_dup(vcodec_value));
- switch (vcodec)
- {
- case HB_VCODEC_X264:
- {
- if (hb_value_get_bool(
- hb_dict_get(preset, "x264UseAdvancedOptions")))
- {
- hb_dict_set(video_dict, "Options",
- hb_value_dup(hb_dict_get(preset, "x264Option")));
- break;
- }
- }
- // Falling through to next case...
-
- case HB_VCODEC_X265:
- {
- hb_value_t *value, *array;
- if ((value = hb_dict_get(preset, "VideoPreset")) != NULL)
- hb_dict_set(video_dict, "Preset", hb_value_dup(value));
- if ((value = hb_dict_get(preset, "VideoProfile")) != NULL)
- hb_dict_set(video_dict, "Profile", hb_value_dup(value));
- if ((value = hb_dict_get(preset, "VideoLevel")) != NULL)
- hb_dict_set(video_dict, "Level", hb_value_dup(value));
- if ((value = hb_dict_get(preset, "VideoOptionExtra")) != NULL)
- hb_dict_set(video_dict, "Options", hb_value_dup(value));
- array = hb_value_array_init();
- if ((value = hb_dict_get(preset, "VideoTune")) != NULL)
- hb_value_array_append(array, hb_value_dup(value));
- if (vcodec == HB_VCODEC_X264)
- {
- if (hb_value_get_bool(hb_dict_get(preset, "x264FastDecode")))
- hb_value_array_append(array, hb_value_string("fastdecode"));
- if (hb_value_get_bool(hb_dict_get(preset, "x264ZeroLatency")))
- hb_value_array_append(array, hb_value_string("zerolatency"));
- }
- if (hb_value_array_len(array) > 0)
- hb_dict_set(video_dict, "Tune",
- hb_value_xform(array, HB_VALUE_TYPE_STRING));
- hb_value_decref(array);
- } break;
-
- case HB_VCODEC_FFMPEG_MPEG2:
- case HB_VCODEC_FFMPEG_MPEG4:
- case HB_VCODEC_FFMPEG_VP8:
- {
- hb_value_t *value;
- if ((value = hb_dict_get(preset, "VideoOptionExtra")) != NULL)
- hb_dict_set(video_dict, "Options", hb_value_dup(value));
- } break;
- case HB_VCODEC_THEORA:
- default:
- {
- } break;
+ if (vcodec == HB_VCODEC_X264 &&
+ hb_value_get_bool(hb_dict_get(preset, "x264UseAdvancedOptions")))
+ {
+ hb_dict_set(video_dict, "Options",
+ hb_value_dup(hb_dict_get(preset, "x264Option")));
+ }
+ else
+ {
+ if ((value = hb_dict_get(preset, "VideoPreset")) != NULL)
+ hb_dict_set(video_dict, "Preset", hb_value_dup(value));
+ if ((value = hb_dict_get(preset, "VideoProfile")) != NULL)
+ hb_dict_set(video_dict, "Profile", hb_value_dup(value));
+ if ((value = hb_dict_get(preset, "VideoLevel")) != NULL)
+ hb_dict_set(video_dict, "Level", hb_value_dup(value));
+ if ((value = hb_dict_get(preset, "VideoTune")) != NULL)
+ hb_dict_set(video_dict, "Tune", hb_value_dup(value));
+ if ((value = hb_dict_get(preset, "VideoOptionExtra")) != NULL)
+ hb_dict_set(video_dict, "Options", hb_value_dup(value));
}
- int vqtype = hb_value_get_int(hb_dict_get(preset, "VideoQualityType"));
+
+ vqtype = hb_value_get_int(hb_dict_get(preset, "VideoQualityType"));
if (vqtype == 2) // Constant quality
{
hb_dict_set(video_dict, "Quality",
hb_value_xform(hb_dict_get(preset, "VideoQualitySlider"),
HB_VALUE_TYPE_DOUBLE));
+ hb_dict_set(video_dict, "Bitrate", hb_value_int(-1));
}
else if (vqtype == 1) // ABR
{
@@ -1584,13 +1373,17 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
hb_dict_set(video_dict, "Turbo",
hb_value_xform(hb_dict_get(preset, "VideoTurboTwoPass"),
HB_VALUE_TYPE_BOOL));
+ hb_dict_set(video_dict, "Quality", hb_value_double(-1.0));
}
else
{
- hb_value_t *value = hb_dict_get(preset, "VideoQualitySlider");
+ value = hb_dict_get(preset, "VideoQualitySlider");
if (value != NULL && hb_value_get_double(value) >= 0)
+ {
hb_dict_set(video_dict, "Quality",
hb_value_xform(value, HB_VALUE_TYPE_DOUBLE));
+ hb_dict_set(video_dict, "Bitrate", hb_value_int(-1));
+ }
else
{
hb_dict_set(video_dict, "Bitrate",
@@ -1602,15 +1395,15 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
hb_dict_set(video_dict, "Turbo",
hb_value_xform(hb_dict_get(preset, "VideoTurboTwoPass"),
HB_VALUE_TYPE_BOOL));
+ hb_dict_set(video_dict, "Quality", hb_value_double(-1.0));
}
}
- hb_dict_t *qsv = hb_dict_get(video_dict, "QSV");
+ qsv = hb_dict_get(video_dict, "QSV");
if (qsv == NULL)
{
qsv = hb_dict_init();
hb_dict_set(video_dict, "QSV", qsv);
}
- hb_value_t *value;
if ((value = hb_dict_get(preset, "VideoQSVDecode")) != NULL)
{
hb_dict_set(qsv, "Decode",
@@ -1635,7 +1428,193 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
hb_dict_set(video_dict, "HWDecode",
hb_value_xform(value, HB_VALUE_TYPE_BOOL));
}
- video_dict = NULL;
+
+ return 0;
+}
+
+int hb_preset_apply_mux(const hb_dict_t *preset, hb_dict_t *job_dict)
+{
+ hb_value_t *mux_value = hb_dict_get(preset, "FileFormat");
+ int mux;
+ if (hb_value_type(mux_value) == HB_VALUE_TYPE_STRING)
+ {
+ mux = hb_container_get_from_name(hb_value_get_string(mux_value));
+ if (mux == 0)
+ mux = hb_container_get_from_extension(
+ hb_value_get_string(mux_value));
+ }
+ else
+ {
+ mux = hb_value_get_int(mux_value);
+ }
+ hb_container_t *container = hb_container_get_from_format(mux);
+ if (container == NULL)
+ {
+ char *str = hb_value_get_string_xform(mux_value);
+ hb_error("Invalid container (%s)", str);
+ free(str);
+ return -1;
+ }
+
+ hb_dict_t *dest_dict = hb_dict_get(job_dict, "Destination");
+ hb_dict_set(dest_dict, "Mux", hb_value_string(container->short_name));
+
+ if (mux & HB_MUX_MASK_MP4)
+ {
+ hb_dict_t *mp4_dict = hb_dict_init();
+ hb_dict_set(mp4_dict, "Mp4Optimize",
+ hb_value_xform(hb_dict_get(preset, "Mp4HttpOptimize"),
+ HB_VALUE_TYPE_BOOL));
+ hb_dict_set(mp4_dict, "IpodAtom",
+ hb_value_xform(hb_dict_get(preset, "Mp4iPodCompatible"),
+ HB_VALUE_TYPE_BOOL));
+ hb_dict_set(dest_dict, "Mp4Options", mp4_dict);
+ }
+
+ return 0;
+}
+
+int hb_preset_apply_title(hb_handle_t *h, int title_index,
+ const hb_dict_t *preset, hb_dict_t *job_dict)
+{
+ // Apply preset settings that requires the title
+ hb_title_t *title = hb_find_title_by_index(h, title_index);
+ if (title == NULL)
+ return -1;
+
+ int chapters;
+ chapters = hb_value_get_bool(hb_dict_get(preset, "ChapterMarkers"));
+ if (title != NULL && hb_list_count(title->list_chapter) <= 1)
+ chapters = 0;
+
+ // Set "Destination" settings in job
+ hb_dict_t *dest_dict = hb_dict_get(job_dict, "Destination");
+ hb_dict_set(dest_dict, "ChapterMarkers", hb_value_bool(chapters));
+
+ hb_dict_t *filters_dict = hb_dict_get(job_dict, "Filters");
+ hb_value_array_t *filter_list = hb_dict_get(filters_dict, "FilterList");
+
+ // Calculate default job geometry settings
+ hb_geometry_t srcGeo, resultGeo;
+ hb_geometry_settings_t geo;
+ int keep_aspect;
+
+ srcGeo = title->geometry;
+ if (!hb_value_get_bool(hb_dict_get(preset, "PictureAutoCrop")))
+ {
+ geo.crop[0] = hb_value_get_int(hb_dict_get(preset, "PictureTopCrop"));
+ geo.crop[1] = hb_value_get_int(hb_dict_get(preset, "PictureBottomCrop"));
+ geo.crop[2] = hb_value_get_int(hb_dict_get(preset, "PictureLeftCrop"));
+ geo.crop[3] = hb_value_get_int(hb_dict_get(preset, "PictureRightCrop"));
+ }
+ else
+ {
+ memcpy(geo.crop, title->crop, sizeof(geo.crop));
+ }
+ geo.modulus = hb_value_get_int(hb_dict_get(preset, "PictureModulus"));
+ if (geo.modulus < 2)
+ geo.modulus = 2;
+ if (hb_value_get_bool(hb_dict_get(preset, "PictureLooseCrop")))
+ {
+ // Crop a few extra pixels to avoid scaling to fit Modulus
+ int extra1, extra2, crop_width, crop_height, width, height;
+
+ crop_width = srcGeo.width - geo.crop[2] - geo.crop[3];
+ crop_height = srcGeo.height - geo.crop[0] - geo.crop[1];
+ width = MULTIPLE_MOD_DOWN(crop_width, geo.modulus);
+ height = MULTIPLE_MOD_DOWN(crop_height, geo.modulus);
+
+ extra1 = EVEN((crop_height - height) / 2);
+ extra2 = crop_height - height - extra1;
+ geo.crop[0] += extra1;
+ geo.crop[1] += extra2;
+ extra1 = EVEN((crop_width - width) / 2);
+ extra2 = crop_width - width - extra1;
+ geo.crop[2] += extra1;
+ geo.crop[3] += extra2;
+ }
+ hb_value_t *ana_mode_value = hb_dict_get(preset, "PicturePAR");
+ if (hb_value_type(ana_mode_value) == HB_VALUE_TYPE_STRING)
+ {
+ const char *s = hb_value_get_string(ana_mode_value);
+ if (!strcasecmp(s, "none"))
+ geo.mode = 0;
+ else if (!strcasecmp(s, "strict"))
+ geo.mode = 1;
+ else if (!strcasecmp(s, "custom"))
+ geo.mode = 3;
+ else // default loose
+ geo.mode = 2;
+ }
+ else
+ {
+ geo.mode = hb_value_get_int(hb_dict_get(preset, "PicturePAR"));
+ }
+ keep_aspect = hb_value_get_bool(hb_dict_get(preset, "PictureKeepRatio"));
+ if (geo.mode == HB_ANAMORPHIC_STRICT || geo.mode == HB_ANAMORPHIC_LOOSE)
+ keep_aspect = 1;
+ geo.keep = keep_aspect * HB_KEEP_DISPLAY_ASPECT;
+ geo.itu_par = hb_value_get_bool(hb_dict_get(preset, "PictureItuPAR"));
+ geo.maxWidth = hb_value_get_int(hb_dict_get(preset, "PictureWidth"));
+ geo.maxHeight = hb_value_get_int(hb_dict_get(preset, "PictureHeight"));
+ geo.geometry = title->geometry;
+ int width = hb_value_get_int(hb_dict_get(preset, "PictureForceWidth"));
+ int height = hb_value_get_int(hb_dict_get(preset, "PictureForceHeight"));
+ if (width > 0)
+ {
+ geo.geometry.width = width;
+ geo.keep |= HB_KEEP_WIDTH;
+ }
+ else
+ {
+ geo.geometry.width -= geo.crop[2] + geo.crop[3];
+ }
+ if (height > 0)
+ {
+ geo.geometry.height = height;
+ geo.keep |= HB_KEEP_HEIGHT;
+ }
+ else
+ {
+ geo.geometry.height -= geo.crop[0] + geo.crop[1];
+ }
+ if (geo.mode == HB_ANAMORPHIC_CUSTOM && !keep_aspect)
+ {
+ int dar_width;
+ dar_width = hb_value_get_int(hb_dict_get(preset, "PictureDARWidth"));
+ if (dar_width > 0)
+ {
+ geo.geometry.par.num = dar_width;
+ geo.geometry.par.num = geo.geometry.width;
+ }
+ else
+ {
+ geo.geometry.par.num =
+ hb_value_get_int(hb_dict_get(preset, "PicturePARWidth"));
+ geo.geometry.par.num =
+ hb_value_get_int(hb_dict_get(preset, "PicturePARHeight"));
+ }
+ }
+ hb_set_anamorphic_size2(&srcGeo, &geo, &resultGeo);
+ hb_dict_t *par_dict = hb_dict_get(job_dict, "PAR");
+ hb_dict_set(par_dict, "Num", hb_value_int(resultGeo.par.num));
+ hb_dict_set(par_dict, "Den", hb_value_int(resultGeo.par.den));
+ par_dict = NULL;
+
+ hb_dict_t *filter_dict;
+ char *filter_str;
+
+ // Setup scale filter
+ filter_str = hb_strdup_printf("%d:%d:%d:%d:%d:%d",
+ resultGeo.width, resultGeo.height,
+ geo.crop[0], geo.crop[1],
+ geo.crop[2], geo.crop[3]);
+
+ filter_dict = hb_dict_init();
+ hb_dict_set(filter_dict, "ID", hb_value_int(HB_FILTER_CROP_SCALE));
+ hb_dict_set(filter_dict, "Settings", hb_value_string(filter_str));
+ free(filter_str);
+ hb_value_array_append(filter_list, filter_dict);
// Audio settings
if (hb_preset_job_add_audio(h, title_index, preset, job_dict) != 0)
@@ -1648,11 +1627,52 @@ hb_dict_t* hb_preset_job_init(hb_handle_t *h, int title_index,
{
goto fail;
}
+ return 0;
+
+fail:
+ return -1;
+}
+
+/**
+ * Initialize an hb_job_t and return a hb_dict_t representation of the job.
+ * This dict will have key/value pairs compatible with json jobs.
+ * @param h - Pointer to hb_handle_t instance that contains the
+ * specified title_index
+ * @param title_index - Index of hb_title_t to use for job initialization.
+ * Index comes from title->index or "Index" key
+ * 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,
+ const hb_dict_t *preset)
+{
+ hb_title_t *title = hb_find_title_by_index(h, title_index);
+ if (title == NULL)
+ {
+ hb_error("Invalid title index (%d)", title_index);
+ return NULL;
+ }
+
+ hb_job_t *job = hb_job_init(title);
+ hb_dict_t *job_dict = hb_job_to_dict(job);
+ hb_job_close(&job);
+
+ if (hb_preset_apply_mux(preset, job_dict) < 0)
+ goto fail;
+
+ if (hb_preset_apply_video(preset, job_dict) < 0)
+ goto fail;
+
+ if (hb_preset_apply_filters(preset, job_dict) < 0)
+ goto fail;
+
+ if (hb_preset_apply_title(h, title_index, preset, job_dict) < 0)
+ goto fail;
return job_dict;
fail:
- hb_dict_free(&job_dict);
+ hb_value_free(&job_dict);
return NULL;
}
@@ -2099,6 +2119,28 @@ static void import_video(hb_value_t *preset)
if ((val = hb_dict_get(preset, "x264OptionExtra")) != NULL)
hb_dict_set(preset, "VideoOptionExtra", hb_value_dup(val));
+ // Remove invalid "none" tune from VideoTune. Frontends should
+ // be removing this before saving a preset.
+ if ((val = hb_dict_get(preset, "VideoTune")) != NULL)
+ {
+ const char *tune;
+ tune = hb_value_get_string(val);
+ // "none" is not a valid tune, but is used by HandBrake
+ // to indicate no tune options.
+ if (tune != NULL && !strncasecmp(tune, "none", 4))
+ {
+ tune += 4;
+ if (tune[0] == ',')
+ {
+ tune++;
+ }
+ }
+ if (tune != NULL)
+ {
+ hb_dict_set(preset, "VideoTune", hb_value_string(tune));
+ }
+ }
+
if (hb_value_get_int(hb_dict_get(preset, "VideoQualityType")) == 0)
{
// Target size no longer supported
diff --git a/libhb/preset.h b/libhb/preset.h
index a24b45cf2..d9ca23394 100644
--- a/libhb/preset.h
+++ b/libhb/preset.h
@@ -114,6 +114,23 @@ hb_value_t * hb_presets_get(void);
// Get list of all presets registered with libhb as json string
char * hb_presets_get_json(void);
+// Apply preset Muxer settings to a job
+int hb_preset_apply_mux(const hb_dict_t *preset, hb_dict_t *job_dict);
+
+// Apply preset Video settings to a job
+int hb_preset_apply_video(const hb_dict_t *preset, hb_dict_t *job_dict);
+
+// Apply preset Filter settings to a job
+//
+// Note that this does not apply scale filter settings. A title is
+// required to set the default scale filter settings, so this filter
+// is applied in hb_preset_apply_title()
+int hb_preset_apply_filters(const hb_dict_t *preset, hb_dict_t *job_dict);
+
+// Apply preset settings that require a title to a job
+int hb_preset_apply_title(hb_handle_t *h, int title_index,
+ const hb_dict_t *preset, hb_dict_t *job_dict);
+
// Initialize a job from the given title and preset
hb_dict_t * hb_preset_job_init(hb_handle_t *h, int title_index,
const hb_dict_t *preset);