#include "settings.h"
#include "callbacks.h"
#include "subtitlehandler.h"
+#include "audiohandler.h"
#include "x264handler.h"
#include "preview.h"
#include "values.h"
}
}
+static options_map_t d_when_complete_opts[] =
+{
+ {"Do Nothing", "nothing", 0, "0"},
+ {"Show Notification", "notify", 1, "1"},
+ {"Put Computer To Sleep", "sleep", 2, "2"},
+ {"Shutdown Computer", "shutdown", 3, "3"},
+};
+combo_opts_t when_complete_opts =
+{
+ sizeof(d_when_complete_opts)/sizeof(options_map_t),
+ d_when_complete_opts
+};
+
static options_map_t d_par_opts[] =
{
{"Off", "0", 0, "0"},
d_logging_opts
};
+static options_map_t d_log_longevity_opts[] =
+{
+ {"Week", "week", 7, "7"},
+ {"Month", "month", 30, "30"},
+ {"Year", "year", 365, "365"},
+ {"Immortal", "immortal", 366, "366"},
+};
+combo_opts_t log_longevity_opts =
+{
+ sizeof(d_log_longevity_opts)/sizeof(options_map_t),
+ d_log_longevity_opts
+};
+
+static options_map_t d_appcast_update_opts[] =
+{
+ {"Never", "never", 0, "never"},
+ {"Daily", "daily", 1, "daily"},
+ {"Weekly", "weekly", 2, "weekly"},
+ {"Monthly", "monthly", 3, "monthly"},
+};
+combo_opts_t appcast_update_opts =
+{
+ sizeof(d_appcast_update_opts)/sizeof(options_map_t),
+ d_appcast_update_opts
+};
+
static options_map_t d_vqual_granularity_opts[] =
{
{"0.2", "0.2", 0.2, "0.2"},
{
{"MKV", "mkv", HB_MUX_MKV, "mkv"},
{"MP4", "mp4", HB_MUX_MP4, "mp4"},
- {"M4V", "m4v", HB_MUX_MP4, "m4v"},
};
combo_opts_t container_opts =
{
static options_map_t d_detel_opts[] =
{
- {"None", "none", 0, ""},
+ {"Off", "off", 0, ""},
{"Custom", "custom", 1, ""},
{"Default","default",2, NULL},
};
static options_map_t d_decomb_opts[] =
{
- {"None", "none", 0, ""},
+ {"Off", "off", 0, ""},
{"Custom", "custom", 1, ""},
{"Default","default",2, NULL},
};
static options_map_t d_deint_opts[] =
{
- {"None", "none", 0, ""},
+ {"Off", "off", 0, ""},
{"Custom", "custom", 1, ""},
{"Fast", "fast", 2, "-1:-1:-1:0:1"},
{"Slow", "slow", 3, "2:-1:-1:0:1"},
static options_map_t d_denoise_opts[] =
{
- {"None", "none", 0, ""},
+ {"Off", "off", 0, ""},
{"Custom", "custom", 1, ""},
{"Weak", "weak", 2, "2:1:2:3"},
{"Medium", "medium", 3, "3:2:2:3"},
static options_map_t d_vcodec_opts[] =
{
{"H.264 (x264)", "x264", HB_VCODEC_X264, ""},
- {"MPEG-4 (FFMPEG)", "ffmpeg", HB_VCODEC_FFMPEG, ""},
- {"Theora", "theora", HB_VCODEC_THEORA, ""},
+ {"MPEG-4 (FFmpeg)", "ffmpeg", HB_VCODEC_FFMPEG, ""},
+ {"VP3 (Theora)", "theora", HB_VCODEC_THEORA, ""},
};
combo_opts_t vcodec_opts =
{
static options_map_t d_acodec_opts[] =
{
- {"AAC (faac)", "faac", HB_ACODEC_FAAC, "faac"},
- {"MP3 (lame)", "lame", HB_ACODEC_LAME, "lame"},
+ {"AAC (faac)", "faac", HB_ACODEC_FAAC, "faac"},
+ {"MP3 (lame)", "lame", HB_ACODEC_LAME, "lame"},
{"Vorbis", "vorbis", HB_ACODEC_VORBIS, "vorbis"},
- {"AC3 (pass-thru)", "ac3", HB_ACODEC_AC3, "ac3"},
- {"DTS (pass-thru)", "dts", HB_ACODEC_DCA, "dts"},
- {"Auto Pass-Thru", "auto", HB_ACODEC_DCA|HB_ACODEC_AC3, "auto"},
+ {"AC3 (pass-thru)", "ac3", HB_ACODEC_AC3, "ac3"},
+ {"DTS (pass-thru)", "dts", HB_ACODEC_DCA, "dts"},
+ {"Choose For Me", "auto", HB_ACODEC_MASK, "auto"},
};
combo_opts_t acodec_opts =
{
{"7", "7", 7, "7"},
{"8", "8", 8, "8"},
{"9", "9", 9, "9"},
+ {"10", "10", 10, "10"},
};
combo_opts_t subme_opts =
{
combo_name_map_t combo_name_map[] =
{
+ {"WhenComplete", &when_complete_opts},
{"PicturePAR", &par_opts},
{"PictureModulus", &alignment_opts},
{"LoggingLevel", &logging_opts},
+ {"LogLongevity", &log_longevity_opts},
+ {"check_updates", &appcast_update_opts},
{"VideoQualityGranularity", &vqual_granularity_opts},
{"FileFormat", &container_opts},
{"PictureDeinterlace", &deint_opts},
{NULL, NULL}
};
+const gchar *srt_codeset_table[] =
+{
+ "ANSI_X3.4-1968",
+ "ANSI_X3.4-1986",
+ "ANSI_X3.4",
+ "ANSI_X3.110-1983",
+ "ANSI_X3.110",
+ "ASCII",
+ "ECMA-114",
+ "ECMA-118",
+ "ECMA-128",
+ "ECMA-CYRILLIC",
+ "IEC_P27-1",
+ "ISO-8859-1",
+ "ISO-8859-2",
+ "ISO-8859-3",
+ "ISO-8859-4",
+ "ISO-8859-5",
+ "ISO-8859-6",
+ "ISO-8859-7",
+ "ISO-8859-8",
+ "ISO-8859-9",
+ "ISO-8859-9E",
+ "ISO-8859-10",
+ "ISO-8859-11",
+ "ISO-8859-13",
+ "ISO-8859-14",
+ "ISO-8859-15",
+ "ISO-8859-16",
+ "UTF-7",
+ "UTF-8",
+ "UTF-16",
+ "UTF-16LE",
+ "UTF-16BE",
+ "UTF-32",
+ "UTF-32LE",
+ "UTF-32BE",
+ NULL
+};
+#define SRT_TABLE_SIZE (sizeof(srt_codeset_table)/ sizeof(char*)-1)
+
#if 0
typedef struct iso639_lang_t
{
{ "Cree", "", "cr", "cre" },
{ "Czech", "", "cs", "ces", "cze" },
{ "Danish", "Dansk", "da", "dan" },
+ { "German", "Deutsch", "de", "deu", "ger" },
{ "Divehi", "", "dv", "div" },
- { "Dutch", "Nederlands", "nl", "nld", "dut" },
{ "Dzongkha", "", "dz", "dzo" },
{ "English", "English", "en", "eng" },
+ { "Spanish", "Espanol", "es", "spa" },
{ "Esperanto", "", "eo", "epo" },
{ "Estonian", "", "et", "est" },
{ "Ewe", "", "ee", "ewe" },
{ "Faroese", "", "fo", "fao" },
{ "Fijian", "", "fj", "fij" },
- { "Finnish", "Suomi", "fi", "fin" },
{ "French", "Francais", "fr", "fra", "fre" },
{ "Western Frisian", "", "fy", "fry" },
{ "Fulah", "", "ff", "ful" },
{ "Georgian", "", "ka", "kat", "geo" },
- { "German", "Deutsch", "de", "deu", "ger" },
{ "Gaelic (Scots)", "", "gd", "gla" },
{ "Irish", "", "ga", "gle" },
{ "Galician", "", "gl", "glg" },
{ "Herero", "", "hz", "her" },
{ "Hindi", "", "hi", "hin" },
{ "Hiri Motu", "", "ho", "hmo" },
- { "Hungarian", "Magyar", "hu", "hun" },
+ { "Croatian", "Hrvatski", "hr", "hrv", "scr" },
{ "Igbo", "", "ig", "ibo" },
- { "Icelandic", "Islenska", "is", "isl", "ice" },
{ "Ido", "", "io", "ido" },
+ { "Icelandic", "Islenska", "is", "isl", "ice" },
{ "Sichuan Yi", "", "ii", "iii" },
{ "Inuktitut", "", "iu", "iku" },
{ "Interlingue", "", "ie", "ile" },
{ "Luba-Katanga", "", "lu", "lub" },
{ "Ganda", "", "lg", "lug" },
{ "Macedonian", "", "mk", "mkd", "mac" },
+ { "Hungarian", "Magyar", "hu", "hun" },
{ "Marshallese", "", "mh", "mah" },
{ "Malayalam", "", "ml", "mal" },
{ "Maori", "", "mi", "mri", "mao" },
{ "Mongolian", "", "mn", "mon" },
{ "Nauru", "", "na", "nau" },
{ "Navajo", "", "nv", "nav" },
+ { "Dutch", "Nederlands", "nl", "nld", "dut" },
{ "Ndebele, South", "", "nr", "nbl" },
{ "Ndebele, North", "", "nd", "nde" },
{ "Ndonga", "", "ng", "ndo" },
{ "Nepali", "", "ne", "nep" },
+ { "Norwegian", "Norsk", "no", "nor" },
{ "Norwegian Nynorsk", "", "nn", "nno" },
{ "Norwegian Bokmål", "", "nb", "nob" },
- { "Norwegian", "Norsk", "no", "nor" },
{ "Chichewa; Nyanja", "", "ny", "nya" },
{ "Occitan", "", "oc", "oci" },
{ "Ojibwa", "", "oj", "oji" },
{ "Sango", "", "sg", "sag" },
{ "Sanskrit", "", "sa", "san" },
{ "Serbian", "", "sr", "srp", "scc" },
- { "Croatian", "Hrvatski", "hr", "hrv", "scr" },
{ "Sinhala", "", "si", "sin" },
{ "Slovak", "", "sk", "slk", "slo" },
{ "Slovenian", "", "sl", "slv" },
{ "Sindhi", "", "sd", "snd" },
{ "Somali", "", "so", "som" },
{ "Sotho, Southern", "", "st", "sot" },
- { "Spanish", "Espanol", "es", "spa" },
{ "Sardinian", "", "sc", "srd" },
{ "Swati", "", "ss", "ssw" },
{ "Sundanese", "", "su", "sun" },
+ { "Finnish", "Suomi", "fi", "fin" },
{ "Swahili", "", "sw", "swa" },
{ "Swedish", "Svenska", "sv", "swe" },
{ "Tahitian", "", "ty", "tah" },
{
if (strcmp(ghb_language_table[ii].iso639_2, str) == 0)
{
- result = ghb_language_table[ii].eng_name;
+ if (ghb_language_table[ii].native_name[0] != 0)
+ result = ghb_language_table[ii].native_name;
+ else
+ result = ghb_language_table[ii].eng_name;
break;
}
}
gint titleindex;
if (track == -2)
- return CC608SUB;
+ return SRTSUB;
if (track < 0)
return VOBSUB;
titleindex = ghb_settings_combo_int(ud->settings, "title");
if (track == -2)
{
- name = "Text";
+ name = "SRT";
goto done;
}
if (track == -1)
break;
case CC708SUB:
case CC608SUB:
- case SRTSUB:
name = "Text";
break;
+ case SRTSUB:
+ name = "SRT";
+ break;
default:
break;
}
return name;
}
+gchar*
+ghb_subtitle_track_lang(signal_user_data_t *ud, gint track)
+{
+ gint titleindex;
+
+ titleindex = ghb_settings_combo_int(ud->settings, "title");
+ if (titleindex < 0)
+ goto fail;
+ if (track == -1)
+ return ghb_get_user_audio_lang(ud, titleindex, 0);
+ if (track < 0)
+ goto fail;
+
+ hb_list_t * list;
+ hb_title_t * title;
+ hb_subtitle_t * sub;
+
+ if (h_scan == NULL)
+ goto fail;
+
+ list = hb_get_titles( h_scan );
+ if( !hb_list_count( list ) )
+ {
+ /* No valid title, stop right there */
+ goto fail;
+ }
+ title = hb_list_item( list, titleindex );
+ if (title == NULL) // Bad titleindex
+ goto fail;
+ sub = hb_list_item( title->list_subtitle, track);
+ if (sub != NULL)
+ return g_strdup(sub->iso639_2);
+
+fail:
+ return g_strdup("und");
+}
gint
ghb_get_title_number(gint titleindex)
grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_VORBIS, TRUE);
grey_combo_box_item(builder, "VideoEncoder", HB_VCODEC_THEORA, TRUE);
}
- else if (container == HB_MUX_AVI)
- {
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_FAAC, TRUE);
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_VORBIS, TRUE);
- grey_combo_box_item(builder, "VideoEncoder", HB_VCODEC_THEORA, TRUE);
- }
- else if (container == HB_MUX_OGM)
- {
- grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_FAAC, TRUE);
- }
gboolean allow_mono = TRUE;
gboolean allow_stereo = TRUE;
gboolean allow_dolby = TRUE;
gboolean allow_dpl2 = TRUE;
gboolean allow_6ch = TRUE;
+ allow_mono = acodec & ~HB_ACODEC_LAME;
+ allow_6ch = acodec & ~HB_ACODEC_LAME;
if (audio)
{
- allow_mono =
- (audio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA)) &&
- (acodec != HB_ACODEC_LAME);
+ allow_mono = allow_mono &&
+ (audio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA));
gint layout = audio->in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK;
allow_stereo =
((layout == HB_INPUT_CH_LAYOUT_MONO && !allow_mono) || layout >= HB_INPUT_CH_LAYOUT_STEREO);
(layout == HB_INPUT_CH_LAYOUT_3F2R) ||
(layout == HB_INPUT_CH_LAYOUT_DOLBY);
allow_dpl2 = (layout == HB_INPUT_CH_LAYOUT_3F2R);
- allow_6ch =
+ allow_6ch = allow_6ch &&
(audio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA)) &&
- (acodec != HB_ACODEC_LAME) &&
(layout == HB_INPUT_CH_LAYOUT_3F2R) &&
(audio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE);
}
}
gint
+ghb_get_best_audio_bitrate(gint acodec, gint br, gint channels)
+{
+ if (acodec & HB_ACODEC_FAAC)
+ {
+ int maxbr = channels * 80;
+ if (br > maxbr)
+ br = maxbr;
+ }
+ return br;
+}
+
+gint
ghb_get_best_mix(gint titleindex, gint track, gint acodec, gint mix)
{
hb_audio_config_t *audio = NULL;
{
allow_mono =
(audio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA)) &&
- (acodec != HB_ACODEC_LAME);
+ (acodec & ~HB_ACODEC_LAME);
gint layout = audio->in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK;
allow_stereo =
((layout == HB_INPUT_CH_LAYOUT_MONO && !allow_mono) || layout >= HB_INPUT_CH_LAYOUT_STEREO);
allow_dpl2 = (layout == HB_INPUT_CH_LAYOUT_3F2R);
allow_6ch =
(audio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA)) &&
- (acodec != HB_ACODEC_LAME) &&
+ (acodec & ~HB_ACODEC_LAME) &&
(layout == HB_INPUT_CH_LAYOUT_3F2R) &&
(audio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE);
}
cell = GTK_CELL_RENDERER(gtk_cell_renderer_text_new());
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), cell, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), cell,
- "text", 0, "sensitive", 1, NULL);
+ "markup", 0, "sensitive", 1, NULL);
}
else
{ // Combo box entry
GtkTreeIter iter;
GtkListStore *store;
gint ii;
+ gchar *str;
g_debug("audio_samplerate_opts_set ()\n");
store = get_combo_box_store(builder, name);
// Add an item for "Same As Source"
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, "Same as source",
+ 0, "<small>Same as source</small>",
1, TRUE,
2, "source",
3, 0.0,
for (ii = 0; ii < count; ii++)
{
gtk_list_store_append(store, &iter);
+ str = g_strdup_printf("<small>%s</small>", rates[ii].string);
gtk_list_store_set(store, &iter,
- 0, rates[ii].string,
+ 0, str,
1, TRUE,
2, rates[ii].string,
3, (gdouble)rates[ii].rate,
4, rates[ii].string,
-1);
+ g_free(str);
}
}
GtkTreeIter iter;
GtkListStore *store;
gint ii;
+ gchar *str;
g_debug("mix_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",
+ 0, "<small>None</small>",
1, TRUE,
2, "none",
3, 0.0,
for (ii = 0; ii < hb_audio_mixdowns_count; ii++)
{
gtk_list_store_append(store, &iter);
+ str = g_strdup_printf("<small>%s</small>",
+ hb_audio_mixdowns[ii].human_readable_name);
gtk_list_store_set(store, &iter,
- 0, hb_audio_mixdowns[ii].human_readable_name,
+ 0, str,
1, TRUE,
2, hb_audio_mixdowns[ii].short_name,
3, (gdouble)hb_audio_mixdowns[ii].amixdown,
4, hb_audio_mixdowns[ii].internal_name,
-1);
+ g_free(str);
+ }
+}
+
+static void
+srt_codeset_opts_set(GtkBuilder *builder, const gchar *name)
+{
+ GtkTreeIter iter;
+ GtkListStore *store;
+ gint ii;
+
+ g_debug("srt_codeset_opts_set ()\n");
+ store = get_combo_box_store(builder, name);
+ gtk_list_store_clear(store);
+ for (ii = 0; ii < SRT_TABLE_SIZE; ii++)
+ {
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, srt_codeset_table[ii],
+ 1, TRUE,
+ 2, srt_codeset_table[ii],
+ 3, (gdouble)ii,
+ 4, srt_codeset_table[ii],
+ -1);
}
+ GtkComboBoxEntry *cbe;
+
+ cbe = GTK_COMBO_BOX_ENTRY(GHB_WIDGET(builder, name));
+ //gtk_combo_box_entry_set_text_column(cbe, 0);
}
static void
gtk_list_store_clear(store);
for (ii = 0; ii < LANG_TABLE_SIZE; ii++)
{
+ const gchar *lang;
+
+ if (ghb_language_table[ii].native_name[0] != 0)
+ lang = ghb_language_table[ii].native_name;
+ else
+ lang = ghb_language_table[ii].eng_name;
+
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, ghb_language_table[ii].eng_name,
+ 0, lang,
1, TRUE,
2, ghb_language_table[ii].iso639_2,
3, (gdouble)ii,
hb_audio_config_t * audio;
gint ii;
gint count = 0;
+ gchar *str;
g_debug("audio_track_opts_set ()\n");
store = get_combo_box_store(builder, name);
// No audio. set some default
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, "No Audio",
+ 0, "<small>No Audio</small>",
1, TRUE,
2, "none",
3, -1.0,
{
audio = (hb_audio_config_t *) hb_list_audio_config_item( title->list_audio, ii );
gtk_list_store_append(store, &iter);
+ str = g_strdup_printf("<small>%s</small>", audio->lang.description);
gtk_list_store_set(store, &iter,
- 0, audio->lang.description,
+ 0, str,
1, TRUE,
2, index_str[ii],
3, (gdouble)ii,
4, index_str[ii],
-1);
+ g_free(str);
audio_track_opts.map[ii].option = audio->lang.description,
audio_track_opts.map[ii].shortOpt = index_str[ii];
audio_track_opts.map[ii].ivalue = ii;
index_str_init(LANG_TABLE_SIZE-1);
for (ii = 0; ii < LANG_TABLE_SIZE; ii++)
{
- subtitle_opts.map[ii+1].option = ghb_language_table[ii].eng_name;
+ const gchar *lang;
+
+ if (ghb_language_table[ii].native_name[0] != 0)
+ lang = ghb_language_table[ii].native_name;
+ else
+ lang = ghb_language_table[ii].eng_name;
+
+ subtitle_opts.map[ii+1].option = lang;
subtitle_opts.map[ii+1].shortOpt = index_str[ii];
subtitle_opts.map[ii+1].ivalue = ii;
subtitle_opts.map[ii+1].svalue = ghb_language_table[ii].iso639_2;
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, ghb_language_table[ii].eng_name,
+ 0, lang,
1, TRUE,
2, index_str[ii],
3, (gdouble)ii,
return titleindex;
}
+gchar*
+ghb_get_source_audio_lang(gint titleindex, gint track)
+{
+ hb_list_t * list;
+ hb_title_t * title;
+ hb_audio_config_t * audio;
+ gchar *lang = NULL;
+
+ g_debug("ghb_lookup_1st_audio_lang ()\n");
+ if (h_scan == NULL)
+ return NULL;
+ list = hb_get_titles( h_scan );
+ title = (hb_title_t*)hb_list_item( list, titleindex );
+ if (title == NULL)
+ return NULL;
+ if (hb_list_count( title->list_audio ) <= track)
+ return NULL;
+
+ audio = hb_list_audio_config_item(title->list_audio, track);
+ if (audio == NULL)
+ return NULL;
+
+ lang = g_strdup(audio->lang.iso639_2);
+ return lang;
+}
+
gint
ghb_find_audio_track(
gint titleindex,
}
gint
+ghb_find_cc_track(gint titleindex)
+{
+ hb_list_t * list;
+ hb_title_t * title;
+ hb_subtitle_t * subtitle;
+ gint count, ii;
+
+ g_debug("ghb_find_cc_track ()\n");
+ if (h_scan == NULL) return -2;
+ list = hb_get_titles( h_scan );
+ title = (hb_title_t*)hb_list_item( list, titleindex );
+ if (title != NULL)
+ {
+ count = hb_list_count( title->list_subtitle );
+ // Try to find an item that matches the preferred language
+ for (ii = 0; ii < count; ii++)
+ {
+ subtitle = (hb_subtitle_t*)hb_list_item( title->list_subtitle, ii );
+ if (subtitle->source == CC608SUB || subtitle->source == CC708SUB)
+ return ii;
+ }
+ }
+ return -2;
+}
+
+gint
ghb_find_subtitle_track(
- gint titleindex,
- const gchar *lang,
- GHashTable *track_indices)
+ gint titleindex,
+ const gchar * lang,
+ gboolean burn,
+ gboolean force,
+ gint source,
+ GHashTable * track_indices)
{
hb_list_t * list;
hb_title_t * title;
used = g_malloc0(count * sizeof(gboolean));
g_hash_table_insert(track_indices, g_strdup(lang), used);
}
+ // Try to find an item that matches the preferred language and source
+ for (ii = 0; ii < count; ii++)
+ {
+ if (used[ii])
+ continue;
+
+ subtitle = (hb_subtitle_t*)hb_list_item( title->list_subtitle, ii );
+ if (source == subtitle->source &&
+ ((strcmp(lang, subtitle->iso639_2) == 0) ||
+ (strcmp(lang, "und") == 0)))
+ {
+ used[ii] = TRUE;
+ return ii;
+ }
+ }
// Try to find an item that matches the preferred language
for (ii = 0; ii < count; ii++)
{
continue;
subtitle = (hb_subtitle_t*)hb_list_item( title->list_subtitle, ii );
- if ((strcmp(lang, subtitle->iso639_2) == 0) ||
- (strcmp(lang, "und") == 0))
+ if (((burn || force) && (subtitle->source == VOBSUB)) &&
+ ((strcmp(lang, subtitle->iso639_2) == 0) ||
+ (strcmp(lang, "und") == 0)))
{
used[ii] = TRUE;
return ii;
}
}
+static void
+small_opts_set(GtkBuilder *builder, const gchar *name, combo_opts_t *opts)
+{
+ GtkTreeIter iter;
+ GtkListStore *store;
+ gint ii;
+ gchar *str;
+
+ g_debug("generic_opts_set ()\n");
+ if (name == NULL || opts == NULL) return;
+ store = get_combo_box_store(builder, name);
+ gtk_list_store_clear(store);
+ for (ii = 0; ii < opts->count; ii++)
+ {
+ gtk_list_store_append(store, &iter);
+ str = g_strdup_printf("<small>%s</small>", opts->map[ii].option);
+ gtk_list_store_set(store, &iter,
+ 0, str,
+ 1, TRUE,
+ 2, opts->map[ii].shortOpt,
+ 3, opts->map[ii].ivalue,
+ 4, opts->map[ii].svalue,
+ -1);
+ g_free(str);
+ }
+}
+
combo_opts_t*
find_combo_table(const gchar *name)
{
return lookup_video_rate_int(gval);
else if (strcmp(name, "AudioMixdown") == 0)
return lookup_mix_int(gval);
- else if (strcmp(name, "SourceAudioLang") == 0)
+ else if (strcmp(name, "SrtLanguage") == 0)
+ return lookup_audio_lang_int(gval);
+ else if (strcmp(name, "PreferredLanguage") == 0)
return lookup_audio_lang_int(gval);
else
{
return lookup_video_rate_int(gval);
else if (strcmp(name, "AudioMixdown") == 0)
return lookup_mix_int(gval);
- else if (strcmp(name, "SourceAudioLang") == 0)
+ else if (strcmp(name, "SrtLanguage") == 0)
+ return lookup_audio_lang_int(gval);
+ else if (strcmp(name, "PreferredLanguage") == 0)
return lookup_audio_lang_int(gval);
else
{
return lookup_video_rate_option(gval);
else if (strcmp(name, "AudioMixdown") == 0)
return lookup_mix_option(gval);
- else if (strcmp(name, "SourceAudioLang") == 0)
+ else if (strcmp(name, "SrtLanguage") == 0)
+ return lookup_audio_lang_option(gval);
+ else if (strcmp(name, "PreferredLanguage") == 0)
return lookup_audio_lang_option(gval);
else
{
return lookup_video_rate_option(gval);
else if (strcmp(name, "AudioMixdown") == 0)
return lookup_mix_option(gval);
- else if (strcmp(name, "SourceAudioLang") == 0)
+ else if (strcmp(name, "SrtLanguage") == 0)
+ return lookup_audio_lang_option(gval);
+ else if (strcmp(name, "PreferredLanguage") == 0)
return lookup_audio_lang_option(gval);
else
{
audio_samplerate_opts_set(ud->builder, "AudioSamplerate", hb_audio_rates, hb_audio_rates_count);
video_rate_opts_set(ud->builder, "VideoFramerate", hb_video_rates, hb_video_rates_count);
mix_opts_set(ud->builder, "AudioMixdown");
- language_opts_set(ud->builder, "SourceAudioLang");
+ language_opts_set(ud->builder, "SrtLanguage");
+ language_opts_set(ud->builder, "PreferredLanguage");
+ srt_codeset_opts_set(ud->builder, "SrtCodeset");
title_opts_set(ud->builder, "title");
audio_track_opts_set(ud->builder, "AudioTrack", user_data);
subtitle_track_opts_set(ud->builder, "SubtitleTrack", user_data);
generic_opts_set(ud->builder, "VideoQualityGranularity", &vqual_granularity_opts);
+ generic_opts_set(ud->builder, "WhenComplete", &when_complete_opts);
generic_opts_set(ud->builder, "PicturePAR", &par_opts);
generic_opts_set(ud->builder, "PictureModulus", &alignment_opts);
generic_opts_set(ud->builder, "LoggingLevel", &logging_opts);
+ generic_opts_set(ud->builder, "LogLongevity", &log_longevity_opts);
+ generic_opts_set(ud->builder, "check_updates", &appcast_update_opts);
generic_opts_set(ud->builder, "FileFormat", &container_opts);
generic_opts_set(ud->builder, "PictureDeinterlace", &deint_opts);
generic_opts_set(ud->builder, "PictureDetelecine", &detel_opts);
generic_opts_set(ud->builder, "PictureDecomb", &decomb_opts);
generic_opts_set(ud->builder, "PictureDenoise", &denoise_opts);
generic_opts_set(ud->builder, "VideoEncoder", &vcodec_opts);
- generic_opts_set(ud->builder, "AudioEncoder", &acodec_opts);
+ small_opts_set(ud->builder, "AudioEncoder", &acodec_opts);
generic_opts_set(ud->builder, "x264_direct", &direct_opts);
generic_opts_set(ud->builder, "x264_b_adapt", &badapt_opts);
generic_opts_set(ud->builder, "x264_me", &me_opts);
video_rate_opts_set(ud->builder, "VideoFramerate", hb_video_rates, hb_video_rates_count);
else if (strcmp(name, "AudioMixdown") == 0)
mix_opts_set(ud->builder, "AudioMixdown");
- else if (strcmp(name, "SourceAudioLang") == 0)
- language_opts_set(ud->builder, "SourceAudioLang");
+ else if (strcmp(name, "SrtLanguage") == 0)
+ language_opts_set(ud->builder, "SrtLanguage");
+ else if (strcmp(name, "PreferredLanguage") == 0)
+ language_opts_set(ud->builder, "PreferredLanguage");
+ else if (strcmp(name, "SrtCodeset") == 0)
+ srt_codeset_opts_set(ud->builder, "SrtCodeset");
else if (strcmp(name, "title") == 0)
title_opts_set(ud->builder, "title");
else if (strcmp(name, "SubtitleTrack") == 0)
init_combo_box(builder, "AudioSamplerate");
init_combo_box(builder, "VideoFramerate");
init_combo_box(builder, "AudioMixdown");
- init_combo_box(builder, "SourceAudioLang");
+ init_combo_box(builder, "SrtLanguage");
+ init_combo_box(builder, "PreferredLanguage");
+ init_combo_box(builder, "SrtCodeset");
init_combo_box(builder, "title");
init_combo_box(builder, "AudioTrack");
for (ii = 0; combo_name_map[ii].name != NULL; ii++)
asettings = ghb_array_get_nth(audio_list, ii);
acodec = ghb_settings_combo_int(asettings, "AudioEncoder");
- if (acodec == HB_ACODEC_AC3)
+ if (acodec & HB_ACODEC_AC3)
return TRUE;
}
return FALSE;
GtkListStore *store;
gchar *str;
- g_debug("audio_rate_opts_add ()\n");
+ g_debug("audio_bitrate_opts_add ()\n");
+
+ if (rate < 8) return;
+
store = get_combo_box_store(builder, name);
if (!find_combo_item_by_int(GTK_TREE_MODEL(store), rate, &iter))
{
- str = g_strdup_printf ("%d", rate);
+ str = g_strdup_printf ("<small>%d</small>", rate);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, str,
}
static void
-audio_bitrate_opts_clean(GtkBuilder *builder, const gchar *name, gint last_rate)
+audio_bitrate_opts_clean(
+ GtkBuilder *builder,
+ const gchar *name,
+ gint first_rate,
+ gint last_rate)
{
GtkTreeIter iter;
GtkListStore *store;
gboolean done = FALSE;
gint ii = 0;
guint last = (guint)last_rate;
+ guint first = (guint)first_rate;
g_debug("audio_bitrate_opts_clean ()\n");
store = get_combo_box_store(builder, name);
{
done = !gtk_list_store_remove(store, &iter);
}
- else if (ivalue > last)
+ else if (ivalue < first || ivalue > last)
{
ii++;
gtk_list_store_set(store, &iter, 1, FALSE, -1);
GtkTreeIter iter;
GtkListStore *store;
gint ii;
+ gchar *str;
g_debug("audio_bitrate_opts_set ()\n");
store = get_combo_box_store(builder, name);
for (ii = 0; ii < hb_audio_bitrates_count; ii++)
{
gtk_list_store_append(store, &iter);
+ str = g_strdup_printf ("<small>%s</small>",
+ hb_audio_bitrates[ii].string);
gtk_list_store_set(store, &iter,
- 0, hb_audio_bitrates[ii].string,
+ 0, str,
1, TRUE,
2, hb_audio_bitrates[ii].string,
3, (gdouble)hb_audio_bitrates[ii].rate,
4, hb_audio_bitrates[ii].string,
-1);
+ g_free(str);
}
}
}
void
-ghb_set_default_bitrate_opts(GtkBuilder *builder, gint last_rate)
+ghb_set_default_bitrate_opts(
+ GtkBuilder *builder,
+ gint first_rate,
+ gint last_rate)
{
- audio_bitrate_opts_clean(builder, "AudioBitrate", last_rate);
+ audio_bitrate_opts_clean(builder, "AudioBitrate", first_rate, last_rate);
}
static ghb_status_t hb_status;
{
gboolean autoscale, keep_aspect, enable_keep_aspect;
gboolean enable_scale_width, enable_scale_height;
- gboolean enable_disp_width, enable_disp_height;
+ gboolean enable_disp_width, enable_disp_height, enable_par;
gint pic_par;
GtkWidget *widget;
enable_scale_width = !autoscale && (pic_par != 1);
enable_scale_height = !autoscale && (pic_par != 1);
enable_disp_width = (pic_par == 3) && !keep_aspect;
+ enable_par = (pic_par == 3) && !keep_aspect;
enable_disp_height = FALSE;
widget = GHB_WIDGET(ud->builder, "PictureModulus");
gtk_widget_set_sensitive(widget, enable_disp_width);
widget = GHB_WIDGET(ud->builder, "PictureDisplayHeight");
gtk_widget_set_sensitive(widget, enable_disp_height);
+ widget = GHB_WIDGET(ud->builder, "PicturePARWidth");
+ gtk_widget_set_sensitive(widget, enable_par);
+ widget = GHB_WIDGET(ud->builder, "PicturePARHeight");
+ gtk_widget_set_sensitive(widget, enable_par);
widget = GHB_WIDGET(ud->builder, "PictureKeepRatio");
gtk_widget_set_sensitive(widget, enable_keep_aspect);
widget = GHB_WIDGET(ud->builder, "autoscale");
if (busy) return;
busy = TRUE;
-
+ if (!ud->dont_clear_presets && (keep_width || keep_height))
+ {
+ ghb_settings_set_int(ud->settings, "PictureWidth", 0);
+ ghb_settings_set_int(ud->settings, "PictureHeight", 0);
+ }
+
// First configure widgets
mod = ghb_settings_combo_int(ud->settings, "PictureModulus");
pic_par = ghb_settings_combo_int(ud->settings, "PicturePAR");
// The scaler crashes if the dimensions are not divisible by 2
// Align mod 2. And so does something in x264_encoder_headers()
job->anamorphic.modulus = mod;
+ job->anamorphic.par_width = title->pixel_aspect_width;
+ job->anamorphic.par_height = title->pixel_aspect_height;
+ job->anamorphic.dar_width = 0;
+ job->anamorphic.dar_height = 0;
+
if (keep_height && pic_par == 2)
- width = ((double)height * crop_width / crop_height) + 0.5;
+ width = ((double)height * crop_width / crop_height) + mod / 2;
job->width = width;
job->height = height;
- if (max_width)
- job->maxWidth = max_width;
- if (max_height)
- job->maxHeight = max_height;
+ job->maxWidth = max_width;
+ job->maxHeight = max_height;
job->crop[0] = crop[0]; job->crop[1] = crop[1];
job->crop[2] = crop[2]; job->crop[3] = crop[3];
if (job->anamorphic.mode == 3 && !keep_aspect)
{
- gint dar_width, dar_height;
+ job->anamorphic.keep_display_aspect = 0;
if (mode & GHB_PIC_KEEP_PAR)
{
- par_width = ghb_settings_get_int(ud->settings,
- "PicturePARWidth");
- par_height = ghb_settings_get_int(ud->settings,
- "PicturePARHeight");
- dar_width = ((gdouble)width * par_width / par_height) + 0.5;
- dar_height = height;
+ job->anamorphic.par_width =
+ ghb_settings_get_int(ud->settings, "PicturePARWidth");
+ job->anamorphic.par_height =
+ ghb_settings_get_int(ud->settings, "PicturePARHeight");
}
else
{
- dar_width = ghb_settings_get_int(ud->settings,
- "PictureDisplayWidth");
- dar_height = ghb_settings_get_int(ud->settings,
- "PictureDisplayHeight");
+ job->anamorphic.dar_width =
+ ghb_settings_get_int(ud->settings,
+ "PictureDisplayWidth");
+ job->anamorphic.dar_height = height;
}
- job->anamorphic.dar_width = dar_width;
- job->anamorphic.dar_height = dar_height;
- job->anamorphic.keep_display_aspect = 0;
}
else
{
- job->anamorphic.dar_width = 0;
- job->anamorphic.dar_height = 0;
job->anamorphic.keep_display_aspect = 1;
}
hb_set_anamorphic_size( job, &width, &height,
&par_width, &par_height );
+ if (job->anamorphic.mode == 3 && !keep_aspect &&
+ mode & GHB_PIC_KEEP_PAR)
+ {
+ // hb_set_anamorphic_size reduces the par, which we
+ // don't want in this case because the user is
+ // explicitely specifying it.
+ par_width = ghb_settings_get_int(ud->settings,
+ "PicturePARWidth");
+ par_height = ghb_settings_get_int(ud->settings,
+ "PicturePARHeight");
+ }
}
else
{
}
ghb_ui_update(ud, "display_aspect", ghb_string_value(str));
g_free(str);
- ghb_ui_update(ud, "par_width", ghb_int64_value(par_width));
- ghb_ui_update(ud, "par_height", ghb_int64_value(par_height));
+ ghb_ui_update(ud, "PicturePARWidth", ghb_int64_value(par_width));
+ ghb_ui_update(ud, "PicturePARHeight", ghb_int64_value(par_height));
ghb_ui_update(ud, "PictureDisplayWidth", ghb_int64_value(disp_width));
ghb_ui_update(ud, "PictureDisplayHeight", ghb_int64_value(height));
busy = FALSE;
job->anamorphic.modulus = 2;
}
- gint deint = ghb_settings_combo_int(settings, "PictureDeinterlace");
- gint decomb = ghb_settings_combo_int(settings, "PictureDecomb");
- job->deinterlace = (!decomb && deint == 0) ? 0 : 1;
-
- gboolean keep_aspect;
- keep_aspect = ghb_settings_get_boolean(settings, "PictureKeepRatio");
- if (job->anamorphic.mode == 3 && !keep_aspect)
+ gboolean decomb_deint = ghb_settings_get_boolean(settings, "PictureDecombDeinterlace");
+ if (decomb_deint)
{
- gint disp_width, disp_height;
- disp_width = ghb_settings_get_int(settings, "PictureDisplayWidth");
- disp_height = ghb_settings_get_int(settings, "PictureDisplayHeight");
- job->anamorphic.dar_width = disp_width;
- job->anamorphic.dar_height = disp_height;
- job->anamorphic.keep_display_aspect = 0;
+ gint decomb = ghb_settings_combo_int(settings, "PictureDecomb");
+ job->deinterlace = (decomb == 0) ? 0 : 1;
}
else
{
- job->anamorphic.keep_display_aspect = 1;
+ gint deint = ghb_settings_combo_int(settings, "PictureDeinterlace");
+ job->deinterlace = (deint == 0) ? 0 : 1;
+ }
+
+ gboolean keep_aspect;
+ keep_aspect = ghb_settings_get_boolean(settings, "PictureKeepRatio");
+ if (job->anamorphic.mode)
+ {
+ job->anamorphic.par_width = job->title->pixel_aspect_width;
+ job->anamorphic.par_height = job->title->pixel_aspect_height;
job->anamorphic.dar_width = 0;
job->anamorphic.dar_height = 0;
+
+ if (job->anamorphic.mode == 3 && !keep_aspect)
+ {
+ job->anamorphic.keep_display_aspect = 0;
+ job->anamorphic.par_width =
+ ghb_settings_get_int(settings, "PicturePARWidth");
+ job->anamorphic.par_height =
+ ghb_settings_get_int(settings, "PicturePARHeight");
+ }
+ else
+ {
+ job->anamorphic.keep_display_aspect = 1;
+ }
}
}
gint index;
gchar *message;
- // deinte 4
+ gboolean decomb_deint = ghb_settings_get_boolean(ud->settings, "PictureDecombDeinterlace");
+ // deinte
index = ghb_settings_combo_int(ud->settings, "PictureDeinterlace");
- if (index == 1)
+ if (!decomb_deint && index == 1)
{
str = ghb_settings_get_string(ud->settings, "PictureDeinterlaceCustom");
- if (!ghb_validate_filter_string(str, 4))
+ if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
"Invalid Deinterlace Settings:\n\n%s\n",
if (index == 1)
{
str = ghb_settings_get_string(ud->settings, "PictureDetelecineCustom");
- if (!ghb_validate_filter_string(str, 6))
+ if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
"Invalid Detelecine Settings:\n\n%s\n",
}
g_free(str);
}
- // decomb 4
+ // decomb
index = ghb_settings_combo_int(ud->settings, "PictureDecomb");
- if (index == 1)
+ if (decomb_deint && index == 1)
{
str = ghb_settings_get_string(ud->settings, "PictureDecombCustom");
- if (!ghb_validate_filter_string(str, 7))
+ if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
"Invalid Decomb Settings:\n\n%s\n",
}
g_free(str);
}
- // denois 4
+ // denois
index = ghb_settings_combo_int(ud->settings, "PictureDenoise");
if (index == 1)
{
str = ghb_settings_get_string(ud->settings, "PictureDenoiseCustom");
- if (!ghb_validate_filter_string(str, 4))
+ if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
"Invalid Denoise Settings:\n\n%s\n",
mux = ghb_settings_combo_int(ud->settings, "FileFormat");
vcodec = ghb_settings_combo_int(ud->settings, "VideoEncoder");
- if ((mux == HB_MUX_MP4 || mux == HB_MUX_AVI) &&
- (vcodec == HB_VCODEC_THEORA))
+ if ((mux == HB_MUX_MP4) && (vcodec == HB_VCODEC_THEORA))
{
- // mp4|avi/theora combination is not supported.
+ // mp4/theora combination is not supported.
message = g_strdup_printf(
- "Theora is not supported in the MP4 and AVI containers.\n\n"
+ "Theora is not supported in the MP4 container.\n\n"
"You should choose a different video codec or container.\n"
"If you continue, FFMPEG will be chosen for you.");
if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue"))
gint mux = ghb_settings_combo_int(ud->settings, "FileFormat");
const GValue *slist, *settings;
- gint count, ii, track, source;
+ gint count, ii, source;
gboolean burned, one_burned = FALSE;
slist = ghb_settings_get_value(ud->settings, "subtitle_list");
for (ii = 0; ii < count; ii++)
{
settings = ghb_array_get_nth(slist, ii);
- track = ghb_settings_combo_int(settings, "SubtitleTrack");
+ source = ghb_settings_get_int(settings, "SubtitleSource");
burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
- source = ghb_subtitle_track_source(ud, track);
if (burned && one_burned)
{
// MP4 can only handle burned vobsubs. make sure there isn't
"Your chosen container does not support soft bitmap subtitles.\n\n"
"You should change your subtitle selections.\n"
"If you continue, some subtitles will be lost.");
- if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue"))
+ if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message,
+ "Cancel", "Continue"))
{
g_free(message);
return FALSE;
g_free(message);
break;
}
+ if (source == SRTSUB)
+ {
+ gchar *filename;
+
+ filename = ghb_settings_get_string(settings, "SrtFile");
+ if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
+ {
+ message = g_strdup_printf(
+ "Srt file does not exist or not a regular file.\n\n"
+ "You should choose a valid file.\n"
+ "If you continue, this subtitle will be ignored.");
+ if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message,
+ "Cancel", "Continue"))
+ {
+ g_free(message);
+ return FALSE;
+ }
+ g_free(message);
+ break;
+ }
+ }
}
return TRUE;
}
+gint
+ghb_select_audio_codec(signal_user_data_t *ud, gint track)
+{
+ hb_list_t * list;
+ hb_title_t * title;
+ hb_audio_config_t *audio;
+
+ if (h_scan == NULL) return -1;
+ list = hb_get_titles( h_scan );
+ if( !hb_list_count( list ) )
+ {
+ return -1;
+ }
+
+ gint titleindex;
+
+ titleindex = ghb_settings_combo_int(ud->settings, "title");
+ title = hb_list_item( list, titleindex );
+ if (title == NULL) return -1;
+
+ gint mux = ghb_settings_combo_int(ud->settings, "FileFormat");
+
+ if (track < 0 || track >= hb_list_count(title->list_audio))
+ return -1;
+
+ audio = (hb_audio_config_t *) hb_list_audio_config_item(
+ title->list_audio, track );
+ if (mux == HB_MUX_MP4)
+ {
+ if (audio->in.codec == HB_ACODEC_AC3)
+ return audio->in.codec;
+ else
+ return HB_ACODEC_FAAC;
+ }
+ else
+ {
+ if (audio->in.codec == HB_ACODEC_AC3 || audio->in.codec == HB_ACODEC_DCA)
+ return audio->in.codec;
+ else
+ return HB_ACODEC_LAME;
+ }
+}
+
+const gchar*
+ghb_select_audio_codec_str(signal_user_data_t *ud, gint track)
+{
+ gint acodec, ii;
+
+ acodec = ghb_select_audio_codec(ud, track);
+ for (ii = 0; ii < acodec_opts.count; ii++)
+ {
+ if (acodec_opts.map[ii].ivalue == acodec)
+ return acodec_opts.map[ii].option;
+ }
+ return "Unknown";
+}
+
gboolean
ghb_validate_audio(signal_user_data_t *ud)
{
asettings = ghb_array_get_nth(audio_list, ii);
gint track = ghb_settings_combo_int(asettings, "AudioTrack");
gint codec = ghb_settings_combo_int(asettings, "AudioEncoder");
+ if (codec == HB_ACODEC_MASK)
+ continue;
+
taudio = (hb_audio_config_t *) hb_list_audio_config_item(
title->list_audio, track );
if (!(taudio->in.codec & codec) &&
return FALSE;
}
g_free(message);
- if (mux == HB_MUX_AVI)
+ if (mux == HB_MUX_MKV)
{
codec = HB_ACODEC_LAME;
}
codec = HB_ACODEC_FAAC;
}
}
- else if (mux == HB_MUX_AVI)
- {
- mux_s = "AVI";
- // avi/faac|vorbis combination is not supported.
- if (codec == HB_ACODEC_FAAC)
- {
- a_unsup = "FAAC";
- codec = HB_ACODEC_LAME;
- }
- if (codec == HB_ACODEC_VORBIS)
- {
- a_unsup = "Vorbis";
- codec = HB_ACODEC_LAME;
- }
- }
- else if (mux == HB_MUX_OGM)
- {
- mux_s = "OGM";
- // avi/faac|vorbis combination is not supported.
- if (codec == HB_ACODEC_FAAC)
- {
- a_unsup = "FAAC";
- codec = HB_ACODEC_VORBIS;
- }
- if (codec == HB_ACODEC_AC3)
- {
- a_unsup = "AC-3";
- codec = HB_ACODEC_VORBIS;
- }
- if (codec == HB_ACODEC_DCA)
- {
- a_unsup = "DTS";
- codec = HB_ACODEC_VORBIS;
- }
- }
if (a_unsup)
{
message = g_strdup_printf(
gboolean allow_6ch = TRUE;
allow_mono =
(taudio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA)) &&
- (codec != HB_ACODEC_LAME);
+ (codec & ~HB_ACODEC_LAME);
gint layout = taudio->in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK;
allow_stereo =
((layout == HB_INPUT_CH_LAYOUT_MONO && !allow_mono) || layout >= HB_INPUT_CH_LAYOUT_STEREO);
allow_dpl2 = (layout == HB_INPUT_CH_LAYOUT_3F2R);
allow_6ch =
(taudio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA)) &&
- (codec != HB_ACODEC_LAME) &&
+ (codec & ~HB_ACODEC_LAME) &&
(layout == HB_INPUT_CH_LAYOUT_3F2R) &&
(taudio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE);
job = title->job;
if (job == NULL) return;
+ job->angle = ghb_settings_get_int(js, "angle");
job->start_at_preview = ghb_settings_get_int(js, "start_frame") + 1;
if (job->start_at_preview)
{
job->crop[3] = ghb_settings_get_int(js, "PictureRightCrop");
+ gboolean decomb_deint = ghb_settings_get_boolean(js, "PictureDecombDeinterlace");
gint decomb = ghb_settings_combo_int(js, "PictureDecomb");
gint deint = ghb_settings_combo_int(js, "PictureDeinterlace");
- if (!decomb)
+ if (!decomb_deint)
job->deinterlace = (deint != 0) ? 1 : 0;
else
job->deinterlace = 0;
job->grayscale = ghb_settings_get_boolean(js, "VideoGrayScale");
+ gboolean keep_aspect;
+ keep_aspect = ghb_settings_get_boolean(js, "PictureKeepRatio");
job->anamorphic.mode = ghb_settings_combo_int(js, "PicturePAR");
job->anamorphic.modulus = ghb_settings_combo_int(js, "PictureModulus");
+ if (job->anamorphic.mode)
+ {
+ job->anamorphic.par_width = title->pixel_aspect_width;
+ job->anamorphic.par_height = title->pixel_aspect_height;
+ job->anamorphic.dar_width = 0;
+ job->anamorphic.dar_height = 0;
+
+ if (job->anamorphic.mode == 3 && !keep_aspect)
+ {
+ job->anamorphic.keep_display_aspect = 0;
+ job->anamorphic.par_width =
+ ghb_settings_get_int(js, "PicturePARWidth");
+ job->anamorphic.par_height =
+ ghb_settings_get_int(js, "PicturePARHeight");
+ }
+ else
+ {
+ job->anamorphic.keep_display_aspect = 1;
+ }
+ }
/* Add selected filters */
job->filters = hb_list_init();
hb_filter_detelecine.settings = detel_str;
hb_list_add( job->filters, &hb_filter_detelecine );
}
- if ( decomb )
+ if ( decomb_deint && decomb )
{
if (decomb != 1)
{
job->height = ghb_settings_get_int(js, "scale_height");
job->vcodec = ghb_settings_combo_int(js, "VideoEncoder");
- if ((job->mux == HB_MUX_MP4 || job->mux == HB_MUX_AVI) &&
- (job->vcodec == HB_VCODEC_THEORA))
+ if ((job->mux == HB_MUX_MP4 ) && (job->vcodec == HB_VCODEC_THEORA))
{
- // mp4|avi/theora combination is not supported.
+ // mp4/theora combination is not supported.
job->vcodec = HB_VCODEC_FFMPEG;
}
if ((job->vcodec == HB_VCODEC_X264) && (job->mux == HB_MUX_MP4))
job->cfr = 1;
}
- // AVI container does not support variable frame rate.
- // OGM supports variable frame rate, but bases all timing on
- // DTS, which breaks when b-frames are used since it is
- // impossible to reconstruct PTS from DTS when the framerate
- // is variable.
- if (job->mux == HB_MUX_AVI || job->mux == HB_MUX_OGM)
- {
- job->cfr = 1;
- }
-
const GValue *audio_list;
gint count, ii;
gint tcount = 0;
title->list_audio, audio.in.track );
if (audio.out.codec & (HB_ACODEC_AC3 | HB_ACODEC_DCA))
{
- if (!(taudio->in.codec & audio.out.codec))
+ if (!(taudio->in.codec & (HB_ACODEC_AC3 | HB_ACODEC_DCA)))
{
- // Not supported. AC3 is passthrough only, so input must be AC3
- if (job->mux == HB_MUX_AVI)
+ // Not supported.
+ // AC3/DTS is passthrough only, so input must be AC3/DTS
+ if (job->mux == HB_MUX_MKV)
{
audio.out.codec = HB_ACODEC_LAME;
}
}
}
if ((job->mux == HB_MUX_MP4) &&
- ((audio.out.codec == HB_ACODEC_LAME) ||
- (audio.out.codec == HB_ACODEC_VORBIS)))
+ ((audio.out.codec & HB_ACODEC_LAME) ||
+ (audio.out.codec & HB_ACODEC_DCA) ||
+ (audio.out.codec & HB_ACODEC_VORBIS)))
{
- // mp4/mp3|vorbis combination is not supported.
+ // mp4/mp3|dts|vorbis combination is not supported.
audio.out.codec = HB_ACODEC_FAAC;
}
- if ((job->mux == HB_MUX_AVI) &&
- ((audio.out.codec == HB_ACODEC_FAAC) ||
- (audio.out.codec == HB_ACODEC_VORBIS)))
- {
- // avi/faac|vorbis combination is not supported.
- audio.out.codec = HB_ACODEC_LAME;
- }
- if ((job->mux == HB_MUX_OGM) &&
- ((audio.out.codec == HB_ACODEC_FAAC) ||
- (audio.out.codec == HB_ACODEC_AC3) ||
- (audio.out.codec == HB_ACODEC_DCA)))
- {
- // ogm/faac|ac3 combination is not supported.
- audio.out.codec = HB_ACODEC_VORBIS;
- }
audio.out.dynamic_range_compression =
ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
if (audio.out.dynamic_range_compression < 1.0)
audio.out.dynamic_range_compression = 0.0;
// It would be better if this were done in libhb for us, but its not yet.
- if (audio.out.codec == HB_ACODEC_AC3 || audio.out.codec == HB_ACODEC_DCA)
+ if (audio.out.codec & (HB_ACODEC_AC3 | HB_ACODEC_DCA))
{
audio.out.mixdown = 0;
}
else
{
+ int channels;
+
audio.out.mixdown = ghb_settings_combo_int(asettings, "AudioMixdown");
+ if (audio.out.mixdown == HB_AMIXDOWN_MONO)
+ channels = 1;
+ else if (audio.out.mixdown == HB_AMIXDOWN_6CH)
+ channels = 6;
+ else
+ channels = 2;
+
// Make sure the mixdown is valid and pick a new one if not.
audio.out.mixdown = ghb_get_best_mix(titleindex,
audio.in.track, audio.out.codec, audio.out.mixdown);
audio.out.samplerate = taudio->in.samplerate;
else
audio.out.samplerate = srate;
+
+ audio.out.bitrate = ghb_get_best_audio_bitrate(
+ audio.out.codec, audio.out.bitrate, channels);
}
// Add it to the jobs audio list
dest_str = ghb_settings_get_string(js, "destination");
job->file = dest_str;
- job->crf = ghb_settings_get_boolean(js, "constant_rate_factor");
const GValue *subtitle_list;
gint subtitle;
gboolean force, burned, def, one_burned = FALSE;
- job->select_subtitle = NULL;
+ ghb_settings_set_boolean(js, "subtitle_scan", FALSE);
subtitle_list = ghb_settings_get_value(js, "subtitle_list");
count = ghb_array_len(subtitle_list);
for (ii = 0; ii < count; ii++)
{
GValue *ssettings;
+ gint source;
ssettings = ghb_array_get_nth(subtitle_list, ii);
- subtitle = ghb_settings_get_int(ssettings, "SubtitleTrack");
force = ghb_settings_get_boolean(ssettings, "SubtitleForced");
burned = ghb_settings_get_boolean(ssettings, "SubtitleBurned");
def = ghb_settings_get_boolean(ssettings, "SubtitleDefaultTrack");
+ source = ghb_settings_get_int(ssettings, "SubtitleSource");
+
+ if (source == SRTSUB)
+ {
+ hb_subtitle_config_t sub_config;
+ gchar *filename, *lang, *code;
+ filename = ghb_settings_get_string(ssettings, "SrtFile");
+ if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
+ {
+ continue;
+ }
+ sub_config.offset = ghb_settings_get_int(ssettings, "SrtOffset");
+ lang = ghb_settings_get_string(ssettings, "SrtLanguage");
+ code = ghb_settings_get_string(ssettings, "SrtCodeset");
+ strncpy(sub_config.src_filename, filename, 128);
+ strncpy(sub_config.src_codeset, code, 40);
+ sub_config.force = 0;
+ sub_config.dest = PASSTHRUSUB;
+ sub_config.default_track = def;
+
+ hb_srt_add( job, &sub_config, lang);
+
+ g_free(filename);
+ g_free(lang);
+ g_free(code);
+ continue;
+ }
+
+ subtitle = ghb_settings_get_int(ssettings, "SubtitleTrack");
if (subtitle == -1)
{
if (!burned && job->mux == HB_MUX_MKV)
// Only allow one subtitle to be burned into the video
if (one_burned)
continue;
+ job->select_subtitle_config.dest = RENDERSUB;
one_burned = TRUE;
}
job->select_subtitle_config.force = force;
job->select_subtitle_config.default_track = def;
job->indepth_scan = 1;
- job->select_subtitle = malloc(sizeof(hb_subtitle_t*));
- *job->select_subtitle = NULL;
+ ghb_settings_set_boolean(js, "subtitle_scan", TRUE);
}
else if (subtitle >= 0)
{
* for the second pass and then off again for the
* second.
*/
- hb_subtitle_t **subtitle_tmp = job->select_subtitle;
- job->select_subtitle = NULL;
job->pass = 1;
job->indepth_scan = 0;
job->x264opts = tmp_x264opts;
}
+ else
+ {
+ job->x264opts = x264opts;
+ }
job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24);
hb_add( h, job );
//if (job->x264opts != NULL)
// g_free(job->x264opts);
- job->select_subtitle = subtitle_tmp;
job->pass = 2;
/*
* On the second pass we turn off subtitle scan so that we
if( s.state == HB_STATE_PAUSED )
{
- hb_resume( h_queue );
+ hb_status.queue.state &= ~GHB_STATE_PAUSED;
+ hb_resume( h_queue );
}
else
{
- hb_pause( h_queue );
+ hb_status.queue.state |= GHB_STATE_PAUSED;
+ hb_pause( h_queue );
}
}