summaryrefslogtreecommitdiffstats
path: root/gtk/src/hb-backend.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/src/hb-backend.c')
-rw-r--r--gtk/src/hb-backend.c227
1 files changed, 210 insertions, 17 deletions
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index fe02eb966..65fa4ae25 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -2040,6 +2040,120 @@ title_opts_set(GtkBuilder *builder, const gchar *name)
titles[ii] = NULL;
}
+static void
+x264_tune_opts_set(GtkBuilder *builder, const gchar *name)
+{
+ GtkTreeIter iter;
+ GtkListStore *store;
+ gint ii, count = 0;
+
+ const char * const *tunes;
+ tunes = hb_x264_tunes();
+ while (tunes && tunes[count]) count++;
+
+ g_debug("x264_tune_opts_set ()\n");
+ store = get_combo_box_store(builder, name);
+ gtk_list_store_clear(store);
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, "None",
+ 1, TRUE,
+ 2, "none",
+ 3, (gdouble)0,
+ 4, "none",
+ -1);
+
+ for (ii = 0; ii < count; ii++)
+ {
+ if (strcmp(tunes[ii], "fastdecode") && strcmp(tunes[ii], "zerolatency"))
+ {
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, tunes[ii],
+ 1, TRUE,
+ 2, tunes[ii],
+ 3, (gdouble)ii + 1,
+ 4, tunes[ii],
+ -1);
+ }
+ }
+}
+
+static void
+x264_profile_opts_set(GtkBuilder *builder, const gchar *name)
+{
+ GtkTreeIter iter;
+ GtkListStore *store;
+ gint ii, count = 0;
+
+ const char * const *profiles;
+ profiles = hb_x264_profiles();
+ while (profiles && profiles[count]) count++;
+
+ g_debug("x264_profile_opts_set ()\n");
+ store = get_combo_box_store(builder, name);
+ gtk_list_store_clear(store);
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, "Auto",
+ 1, TRUE,
+ 2, "auto",
+ 3, (gdouble)0,
+ 4, "auto",
+ -1);
+
+ for (ii = 0; ii < count; ii++)
+ {
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, profiles[ii],
+ 1, TRUE,
+ 2, profiles[ii],
+ 3, (gdouble)ii + 1,
+ 4, profiles[ii],
+ -1);
+ }
+}
+
+static void
+x264_level_opts_set(GtkBuilder *builder, const gchar *name)
+{
+ GtkTreeIter iter;
+ GtkListStore *store;
+ gint ii, count = 0;
+
+ const char * const *levels;
+ levels = hb_h264_levels();
+ while (levels && levels[count]) count++;
+
+ g_debug("x264_level_opts_set ()\n");
+ store = get_combo_box_store(builder, name);
+ gtk_list_store_clear(store);
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, "Auto",
+ 1, TRUE,
+ 2, "auto",
+ 3, (gdouble)0,
+ 4, "auto",
+ -1);
+
+ for (ii = 0; ii < count; ii++)
+ {
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, levels[ii],
+ 1, TRUE,
+ 2, levels[ii],
+ 3, (gdouble)ii + 1,
+ 4, levels[ii],
+ -1);
+ }
+}
+
int
ghb_get_title_count()
{
@@ -2912,6 +3026,9 @@ ghb_update_ui_combo_box(
small_opts_set(ud->builder, "x264_subme", &subme_opts);
small_opts_set(ud->builder, "x264_analyse", &analyse_opts);
small_opts_set(ud->builder, "x264_trellis", &trellis_opts);
+ x264_tune_opts_set(ud->builder, "x264Tune");
+ x264_profile_opts_set(ud->builder, "h264Profile");
+ x264_level_opts_set(ud->builder, "h264Level");
}
else
{
@@ -2941,6 +3058,12 @@ ghb_update_ui_combo_box(
subtitle_track_opts_set(ud->builder, "SubtitleTrack", user_data);
else if (strcmp(name, "AudioTrack") == 0)
audio_track_opts_set(ud->builder, "AudioTrack", user_data);
+ else if (strcmp(name, "x264Tune") == 0)
+ x264_tune_opts_set(ud->builder, "x264Tune");
+ else if (strcmp(name, "h264Profile") == 0)
+ x264_profile_opts_set(ud->builder, "h264Profile");
+ else if (strcmp(name, "h264Level") == 0)
+ x264_level_opts_set(ud->builder, "h264Level");
else
generic_opts_set(ud->builder, name, find_combo_table(name));
}
@@ -2967,6 +3090,9 @@ init_ui_combo_boxes(GtkBuilder *builder)
init_combo_box(builder, "VideoEncoder");
init_combo_box(builder, "AudioEncoder");
init_combo_box(builder, "AudioEncoderFallback");
+ init_combo_box(builder, "x264Tune");
+ init_combo_box(builder, "h264Profile");
+ init_combo_box(builder, "h264Level");
for (ii = 0; combo_name_map[ii].name != NULL; ii++)
{
init_combo_box(builder, combo_name_map[ii].name);
@@ -3020,6 +3146,81 @@ ghb_build_advanced_opts_string(GValue *settings)
return result;
}
+void ghb_set_video_encoder_opts(hb_job_t *job, GValue *js)
+{
+ gint vcodec = ghb_settings_combo_int(js, "VideoEncoder");
+
+ switch (vcodec)
+ {
+ case HB_VCODEC_X264:
+ {
+ if (ghb_settings_get_boolean(js, "x264UseAdvancedOptions"))
+ {
+ char *opts = ghb_settings_get_string(js, "x264Option");
+ hb_job_set_advanced_opts(job, opts);
+ g_free(opts);
+ }
+ else
+ {
+ GString *str = g_string_new("");
+ char *preset = ghb_settings_get_string(js, "x264Preset");
+ char *tune = ghb_settings_get_string(js, "x264Tune");
+ char *profile = ghb_settings_get_string(js, "h264Profile");
+ char *level = ghb_settings_get_string(js, "h264Level");
+ char *opts = ghb_settings_get_string(js, "x264OptionExtra");
+ char *tunes;
+
+ g_string_append_printf(str, "%s", tune);
+ if (ghb_settings_get_boolean(js, "x264FastDecode"))
+ {
+ g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "fastdecode");
+ }
+ if (ghb_settings_get_boolean(js, "x264ZeroLatency"))
+ {
+ g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "zerolatency");
+ }
+ tunes = g_string_free(str, FALSE);
+
+ hb_job_set_x264_preset(job, preset);
+
+ if (tunes != NULL && strcasecmp(tune, "none"))
+ hb_job_set_x264_tune(job, tunes);
+
+ if (profile != NULL && strcasecmp(profile, "auto"))
+ hb_job_set_x264_profile(job, profile);
+
+ if (level != NULL && strcasecmp(level, "auto"))
+ hb_job_set_x264_level(job, level);
+
+ hb_job_set_advanced_opts(job, opts);
+
+ g_free(preset);
+ g_free(tune);
+ g_free(profile);
+ g_free(level);
+ g_free(opts);
+ g_free(tunes);
+ }
+ } break;
+
+ case HB_VCODEC_FFMPEG_MPEG2:
+ case HB_VCODEC_FFMPEG_MPEG4:
+ {
+ gchar *opts = ghb_settings_get_string(js, "lavcOption");
+ if (opts != NULL && opts[0])
+ {
+ hb_job_set_advanced_opts(job, opts);
+ }
+ g_free(opts);
+ } break;
+
+ case HB_VCODEC_THEORA:
+ default:
+ {
+ } break;
+ }
+}
+
void
ghb_part_duration(gint tt, gint sc, gint ec, gint *hh, gint *mm, gint *ss)
{
@@ -4465,7 +4666,6 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
hb_list_t * list;
hb_title_t * title;
hb_job_t * job;
- static gchar *advanced_opts;
gint sub_id = 0;
hb_filter_object_t * filter;
gchar *filter_str;
@@ -4724,6 +4924,13 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
else
cfr = 0;
+ // x264 zero latency requires CFR encode
+ if (ghb_settings_get_boolean(js, "x264ZeroLatency"))
+ {
+ cfr = 1;
+ ghb_log("zerolatency x264 tune selected, forcing constant framerate");
+ }
+
if( vrate_base == 0 )
{
vrate = title->rate;
@@ -4935,19 +5142,6 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
}
- // TODO: libhb holds onto a reference to the advanced_opts and is not
- // finished with it until encoding the job is done. But I can't
- // find a way to get at the job before it is removed in order to
- // free up the memory I am allocating here.
- // The short story is THIS LEAKS.
- advanced_opts = ghb_build_advanced_opts_string(js);
-
- if( advanced_opts && *advanced_opts == '\0' )
- {
- g_free(advanced_opts);
- advanced_opts = NULL;
- }
-
char * meta;
meta = ghb_settings_get_string(js, "MetaName");
@@ -5028,7 +5222,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
*/
job->pass = 1;
job->indepth_scan = 0;
- hb_job_set_advanced_opts(job, advanced_opts);
+ ghb_set_video_encoder_opts(job, js);
/*
* If turbo options have been selected then set job->fastfirstpass
@@ -5059,13 +5253,12 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
}
else
{
- hb_job_set_advanced_opts(job, advanced_opts);
+ ghb_set_video_encoder_opts(job, js);
job->indepth_scan = 0;
job->pass = 0;
job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24);
hb_add( h, job );
}
- g_free(advanced_opts);
hb_job_close(&job);
}