<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="icon_name">gtk-ok</property>
</object>
- <object class="GtkImage" id="srt_add_image">
+ <object class="GtkImage" id="import_add_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</packing>
</child>
<child>
- <object class="GtkBox" id="subtitle_srt_switch_box">
+ <object class="GtkBox" id="subtitle_import_switch_box">
<property name="orientation">horizontal</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Enable settings to import an SRT subtitle file</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
- <signal name="toggled" handler="subtitle_srt_radio_toggled_cb" swapped="no"/>
+ <signal name="toggled" handler="subtitle_import_radio_toggled_cb" swapped="no"/>
</object>
<packing>
<property name="position">1</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
- <object class="GtkGrid" id="subtitle_srt_grid">
+ <object class="GtkGrid" id="subtitle_import_grid">
<property name="visible">True</property>
<property name="row-spacing">2</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="column_spacing">4</property>
<child>
- <object class="GtkLabel" id="srt_lang_label">
+ <object class="GtkLabel" id="import_lang_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="srt_file_label">
+ <object class="GtkLabel" id="import_file_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="srt_offset_label">
+ <object class="GtkLabel" id="import_offset_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</packing>
</child>
<child>
- <object class="GtkComboBox" id="SrtLanguage">
+ <object class="GtkComboBox" id="ImportLanguage">
<property name="valign">GTK_ALIGN_CENTER</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip_text" translatable="yes">Set the language of this subtitle.
This value will be used by players in subtitle menus.</property>
- <signal name="changed" handler="srt_lang_changed_cb" swapped="no"/>
+ <signal name="changed" handler="import_lang_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">1</property>
</packing>
</child>
<child>
- <object class="GtkFileChooserButton" id="SrtFile">
+ <object class="GtkFileChooserButton" id="ImportFile">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Select the SRT file to import.</property>
<property name="local_only">False</property>
<property name="hexpand">True</property>
- <property name="title" translatable="yes">Srt File</property>
- <signal name="selection-changed" handler="srt_file_changed_cb" swapped="no"/>
+ <property name="title" translatable="yes">Import File</property>
+ <signal name="selection-changed" handler="import_file_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">2</property>
</packing>
</child>
<child>
- <object class="GtkSpinButton" id="SrtOffset">
+ <object class="GtkSpinButton" id="ImportOffset">
<property name="width-chars">8</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip_text" translatable="yes">Adjust the offset in milliseconds between video and SRT timestamps</property>
<property name="adjustment">adjustment31</property>
- <signal name="value-changed" handler="srt_offset_changed_cb" swapped="no"/>
+ <signal name="value-changed" handler="import_offset_changed_cb" swapped="no"/>
</object>
<packing>
<property name="top_attach">1</property>
NULL
},
{
- "SrtLanguage",
+ "ImportLanguage",
NULL,
language_opts_set,
NULL
const hb_title_t *title;
if (track == -2)
- return SRTSUB;
+ return IMPORTSRT;
if (track < 0)
return VOBSUB;
title_id = ghb_dict_get_int(settings, "title");
return FALSE;
}
- const GhbValue *slist, *subtitle, *srt;
+ const GhbValue *slist, *subtitle, *import;
gint count, ii, track;
gboolean burned, one_burned = FALSE;
{
subtitle = ghb_array_get(slist, ii);
track = ghb_dict_get_int(subtitle, "Track");
- srt = ghb_dict_get(subtitle, "SRT");
+ import = ghb_dict_get(subtitle, "Import");
burned = track != -1 && ghb_dict_get_bool(subtitle, "Burn");
if (burned && one_burned)
{
{
one_burned = TRUE;
}
- if (srt != NULL)
+ if (import != NULL)
{
const gchar *filename;
- filename = ghb_dict_get_string(srt, "Filename");
+ filename = ghb_dict_get_string(import, "Filename");
if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
{
message = g_strdup_printf(
"chapter_list": [],
"vquality_type_bitrate": false,
"vquality_type_constant": false,
- "SrtLanguage": "und",
+ "ImportLanguage": "und",
"SrtCodeset": "ISO-8859-1",
- "SrtFile": "",
- "SrtOffset": 0,
+ "ImportFile": "",
+ "ImportOffset": 0,
"VideoFramerateCFR": false,
"VideoFrameratePFR": false,
"VideoFramerateVFR": true,
ghb_subtitle_short_description(const GhbValue *subsource,
const GhbValue *subsettings)
{
- GhbValue *srt;
+ GhbValue *import;
char *desc = NULL;
- srt = ghb_dict_get(subsettings, "SRT");
- if (srt != NULL)
+ import = ghb_dict_get(subsettings, "Import");
+ if (import != NULL)
{
+ const gchar *format = "SRT";
const gchar *code;
const gchar *lang;
const iso639_lang_t *iso;
- lang = ghb_dict_get_string(srt, "Language");
- code = ghb_dict_get_string(srt, "Codeset");
+ format = ghb_dict_get_string(import, "Format");
+ lang = ghb_dict_get_string(import, "Language");
+ code = ghb_dict_get_string(import, "Codeset");
iso = lang_lookup(lang);
if (iso != NULL)
lang = iso->eng_name;
}
- desc = g_strdup_printf("%s (%s)(SRT)", lang, code);
+ if (code != NULL)
+ {
+ desc = g_strdup_printf("%s (%s)(%s)", lang, code, format);
+ }
+ else
+ {
+ desc = g_strdup_printf("%s (%s)", lang, format);
+ }
}
else if (subsource == NULL)
{
subtitle_get_track_description(const GhbValue *subsource,
const GhbValue *subsettings)
{
- GhbValue *srt;
+ GhbValue *import;
char *desc = NULL;
- srt = ghb_dict_get(subsettings, "SRT");
- if (srt != NULL)
+ import = ghb_dict_get(subsettings, "Import");
+ if (import != NULL)
{
+ const gchar *format = "SRT";
const gchar *filename, *code;
const gchar *lang;
const iso639_lang_t *iso;
- lang = ghb_dict_get_string(srt, "Language");
- code = ghb_dict_get_string(srt, "Codeset");
- filename = ghb_dict_get_string(srt, "Filename");
+ format = ghb_dict_get_string(import, "Format");
+ lang = ghb_dict_get_string(import, "Language");
+ code = ghb_dict_get_string(import, "Codeset");
+ filename = ghb_dict_get_string(import, "Filename");
iso = lang_lookup(lang);
if (iso != NULL)
gchar *basename;
basename = g_path_get_basename(filename);
- desc = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename);
+ if (code != NULL)
+ {
+ desc = g_strdup_printf("%s (%s)(%s)(%s)",
+ lang, code, format, basename);
+ }
+ else
+ {
+ desc = g_strdup_printf("%s (%s)(%s)", lang, format, basename);
+ }
g_free(basename);
}
else
{
- desc = g_strdup_printf("%s (%s)(SRT)", lang, code);
+ if (code != NULL)
+ {
+ desc = g_strdup_printf("%s (%s)(%s)", lang, code, format);
+ }
+ else
+ {
+ desc = g_strdup_printf("%s (%s)", lang, format);
+ }
}
}
else if (subsource == NULL)
}
for (ii = 0; ii < count; ii++)
{
- GhbValue *subsettings, *subsource, *srt;
+ GhbValue *subsettings, *subsource, *import;
int track;
gboolean force, burn, def;
char * desc;
track = ghb_dict_get_int(subsettings, "Track");
subsource = ghb_array_get(titleSubtitleList, track);
desc = subtitle_get_track_description(subsource, subsettings);
- srt = ghb_dict_get(subsettings, "SRT");
+ import = ghb_dict_get(subsettings, "Import");
force = ghb_dict_get_bool(subsettings, "Forced");
burn = ghb_dict_get_bool(subsettings, "Burn");
def = ghb_dict_get_bool(subsettings, "Default");
if (count + search > 1)
XPRINT("\t");
- if (srt == NULL)
+ if (import == NULL)
{
XPRINT("<small>%s%s%s%s</small>\n", desc,
force ? _(" (Forced Only)") : "",
static int get_sub_source(GhbValue *settings, GhbValue *subsettings)
{
- if (ghb_dict_get(subsettings, "SRT") != NULL)
+ GhbValue *import;
+
+ import = ghb_dict_get(subsettings, "Import");
+ if (import != NULL)
{
- return SRTSUB;
+ const char * format = ghb_dict_get_string(import, "Format");
+ if (format != NULL && !strcasecmp(format, "SSA"))
+ {
+ return IMPORTSSA;
+ }
+ return IMPORTSRT;
}
int title_id = ghb_dict_get_int(settings, "title");
desc = subtitle_get_track_description(settings, subsettings);
info_src = g_strdup_printf("<small>%s</small>", desc);
g_free(desc);
- if (ghb_dict_get(subsettings, "SRT") != NULL)
+ if (ghb_dict_get(subsettings, "Import") != NULL)
{
gint offset;
offset = ghb_dict_get_int(subsettings, "Offset");
static char *
subtitle_get_track_description(GhbValue *settings, GhbValue *subsettings)
{
- GhbValue *srt;
+ GhbValue * import;
char *desc = NULL;
- srt = ghb_dict_get(subsettings, "SRT");
- if (srt != NULL)
+ import = ghb_dict_get(subsettings, "Import");
+ if (import != NULL)
{
- const gchar *filename, *code;
- const gchar *lang;
- const iso639_lang_t *iso;
+ const gchar * format = "SRT";
+ const gchar * filename, * code;
+ const gchar * lang;
+ const iso639_lang_t * iso;
- lang = ghb_dict_get_string(srt, "Language");
- code = ghb_dict_get_string(srt, "Codeset");
- filename = ghb_dict_get_string(srt, "Filename");
+ format = ghb_dict_get_string(import, "Format");
+ filename = ghb_dict_get_string(import, "Filename");
+ lang = ghb_dict_get_string(import, "Language");
+ code = ghb_dict_get_string(import, "Codeset");
iso = lang_lookup(lang);
if (iso != NULL)
gchar *basename;
basename = g_path_get_basename(filename);
- desc = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename);
+ if (code != NULL)
+ {
+ desc = g_strdup_printf("%s (%s)(%s)(%s)",
+ lang, code, format, basename);
+ }
+ else
+ {
+ desc = g_strdup_printf("%s (%s)(%s)", lang, format, basename);
+ }
g_free(basename);
}
else
{
- desc = g_strdup_printf("%s (%s)(SRT)", lang, code);
+ if (code != NULL)
+ {
+ desc = g_strdup_printf("%s (%s)(%s)", lang, code, format);
+ }
+ else
+ {
+ desc = g_strdup_printf("%s (%s)", lang, format);
+ }
}
}
else
int track,
int mux,
gboolean default_track,
- gboolean srt,
+ gboolean import,
+ int source,
gboolean burn,
gboolean *burned)
{
- int source = VOBSUB;
-
- if (track >= 0 && !srt)
+ if (track >= 0 && !import)
{
hb_subtitle_t *subtitle = hb_list_item(title->list_subtitle, track);
source = subtitle->source;
}
- else if (srt)
- {
- source = SRTSUB;
- }
burn |= !hb_subtitle_can_pass(source, mux);
}
GhbValue *subsettings = ghb_dict_new();
- if (srt)
+ if (import)
{
// Set default SRT settings
- GhbValue *srt_dict;
+ GhbValue *import_dict;
const gchar *pref_lang, *dir;
gchar *filename;
- srt_dict = ghb_dict_new();
- hb_dict_set(subsettings, "SRT", srt_dict);
+ import_dict = ghb_dict_new();
+ hb_dict_set(subsettings, "Import", import_dict);
+ ghb_dict_set_string(import_dict, "Format",
+ source == IMPORTSRT ? "SRT" : "SSA");
pref_lang = ghb_dict_get_string(settings, "PreferredLanguage");
- ghb_dict_set_string(srt_dict, "Language", pref_lang);
- ghb_dict_set_string(srt_dict, "Codeset", "UTF-8");
+ ghb_dict_set_string(import_dict, "Language", pref_lang);
+ ghb_dict_set_string(import_dict, "Codeset", "UTF-8");
dir = ghb_dict_get_string(ud->prefs, "SrtDir");
filename = g_strdup_printf("%s/none", dir);
- ghb_dict_set_string(srt_dict, "Filename", filename);
+ ghb_dict_set_string(import_dict, "Filename", filename);
g_free(filename);
}
if (subsettings != NULL)
{
// Update widgets with subsettings
- GhbValue *val, *srt;
+ GhbValue *val, *import;
gboolean burn, force, def;
int source;
mux_id = ghb_dict_get_string(ud->settings, "FileFormat");
mux = ghb_lookup_container_by_name(mux_id);
- srt = ghb_dict_get(subsettings, "SRT");
+ import = ghb_dict_get(subsettings, "Import");
source = get_sub_source(ud->settings, subsettings);
val = ghb_dict_get(subsettings, "Track");
// Hide regular subtitle widgets
widget = GHB_WIDGET(ud->builder, "subtitle_track_box");
- gtk_widget_set_visible(widget, srt == NULL);
-
- // Show SRT subitle widgets
- widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid");
- gtk_widget_set_visible(widget, srt != NULL);
-
- widget = GHB_WIDGET(ud->builder, "subtitle_srt_switch_box");
+ gtk_widget_set_visible(widget, import == NULL);
+
+ // Show import subitle widgets
+ widget = GHB_WIDGET(ud->builder, "subtitle_import_grid");
+ gtk_widget_set_visible(widget, source == IMPORTSRT ||
+ source == IMPORTSSA);
+ widget = GHB_WIDGET(ud->builder, "srt_code_label");
+ gtk_widget_set_visible(widget, source == IMPORTSRT);
+ widget = GHB_WIDGET(ud->builder, "SrtCodeset");
+ gtk_widget_set_visible(widget, source == IMPORTSRT);
+
+ widget = GHB_WIDGET(ud->builder, "subtitle_import_switch_box");
gtk_widget_set_visible(widget, TRUE);
}
else
widget = GHB_WIDGET(ud->builder, "subtitle_track_box");
gtk_widget_set_visible(widget, FALSE);
- widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid");
+ widget = GHB_WIDGET(ud->builder, "subtitle_import_grid");
gtk_widget_set_visible(widget, FALSE);
- widget = GHB_WIDGET(ud->builder, "subtitle_srt_switch_box");
+ widget = GHB_WIDGET(ud->builder, "subtitle_import_switch_box");
gtk_widget_set_visible(widget, FALSE);
}
- if (srt != NULL)
+ if (import != NULL)
{
ghb_ui_update(ud, "SubtitleSrtEnable", ghb_boolean_value(TRUE));
- val = ghb_dict_get(srt, "Language");
- ghb_ui_update(ud, "SrtLanguage", val);
- val = ghb_dict_get(srt, "Codeset");
+ val = ghb_dict_get(import, "Language");
+ ghb_ui_update(ud, "ImportLanguage", val);
+ val = ghb_dict_get(import, "Codeset");
ghb_ui_update(ud, "SrtCodeset", val);
- val = ghb_dict_get(srt, "Filename");
- ghb_ui_update(ud, "SrtFile", val);
+ val = ghb_dict_get(import, "Filename");
+ ghb_ui_update(ud, "ImportFile", val);
val = ghb_dict_get(subsettings, "Offset");
- ghb_ui_update(ud, "SrtOffset", val);
+ ghb_ui_update(ud, "ImportOffset", val);
}
else
{
else
{
// Hide SRT subitle widgets
- widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid");
+ widget = GHB_WIDGET(ud->builder, "subtitle_import_grid");
gtk_widget_set_visible(widget, FALSE);
// Show regular subtitle widgets
}
G_MODULE_EXPORT void
-subtitle_srt_radio_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
+subtitle_import_radio_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
{
GhbValue *subsettings;
gchar *filename;
GhbValue *srt = ghb_dict_new();
- ghb_dict_set(subsettings, "SRT", srt);
+ ghb_dict_set(subsettings, "Import", srt);
pref_lang = ghb_dict_get_string(ud->settings, "PreferredLanguage");
ghb_dict_set_string(srt, "Language", pref_lang);
ghb_dict_set_string(srt, "Codeset", "UTF-8");
}
else
{
- ghb_dict_remove(subsettings, "SRT");
+ ghb_dict_remove(subsettings, "Import");
}
subtitle_update_dialog_widgets(ud, subsettings);
subtitle_list_refresh_selected(ud, subsettings);
}
G_MODULE_EXPORT void
-srt_setting_update(GhbValue *val, const char *name, signal_user_data_t *ud)
+import_setting_update(GhbValue *val, const char *name, signal_user_data_t *ud)
{
GhbValue *subsettings;
subsettings = subtitle_get_selected_settings(ud, NULL);
if (subsettings != NULL)
{
- GhbValue *srt;
- srt = ghb_dict_get(subsettings, "SRT");
- if (srt != NULL)
+ GhbValue * import;
+ import = ghb_dict_get(subsettings, "Import");
+ if (import != NULL)
{
- ghb_dict_set(srt, name, val);
+ ghb_dict_set(import, name, val);
subtitle_list_refresh_selected(ud, subsettings);
ghb_update_summary_info(ud);
ghb_live_reset(ud);
}
G_MODULE_EXPORT void
-srt_offset_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+import_offset_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
ghb_widget_to_setting(ud->settings, widget);
GhbValue *val = ghb_widget_value(widget);
ghb_check_dependency(ud, widget, NULL);
GhbValue *val = ghb_dict_get(ud->settings, "SrtCodeset");
- srt_setting_update(ghb_value_dup(val), "Codeset", ud);
+ import_setting_update(ghb_value_dup(val), "Codeset", ud);
}
G_MODULE_EXPORT void
-srt_file_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+import_file_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
ghb_widget_to_setting(ud->settings, widget);
ghb_check_dependency(ud, widget, NULL);
- GhbValue *val = ghb_dict_get(ud->settings, "SrtFile");
- srt_setting_update(ghb_value_dup(val), "Filename", ud);
+ GhbValue *val = ghb_dict_get(ud->settings, "ImportFile");
+ import_setting_update(ghb_value_dup(val), "Filename", ud);
// Update SrtDir preference
const gchar *filename;
}
G_MODULE_EXPORT void
-srt_lang_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+import_lang_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
ghb_widget_to_setting(ud->settings, widget);
ghb_check_dependency(ud, widget, NULL);
- GhbValue *val = ghb_dict_get(ud->settings, "SrtLanguage");
- srt_setting_update(ghb_value_dup(val), "Language", ud);
+ GhbValue *val = ghb_dict_get(ud->settings, "ImportLanguage");
+ import_setting_update(ghb_value_dup(val), "Language", ud);
}
static void
subsettings == NULL && track < count; track++)
{
subsettings = subtitle_add_track(ud, ud->settings, title, track,
- mux->format, FALSE, FALSE, FALSE, &one_burned);
+ mux->format, FALSE, FALSE, VOBSUB,
+ FALSE, &one_burned);
}
if (subsettings == NULL)
{
subsettings = subtitle_add_track(ud, ud->settings, title, 0,
- mux->format, FALSE, TRUE, FALSE, &one_burned);
+ mux->format, FALSE, TRUE, IMPORTSRT,
+ FALSE, &one_burned);
}
if (subsettings != NULL)
{
for (track = 0; track < count; track++)
{
subtitle_add_track(ud, ud->settings, title, track, mux->format,
- FALSE, FALSE, FALSE, &one_burned);
+ FALSE, FALSE, VOBSUB, FALSE, &one_burned);
}
subtitle_refresh_list_ui(ud);
ghb_update_summary_info(ud);
return 1;
}
-int hb_srt_add( const hb_job_t * job,
+int hb_import_subtitle_add( const hb_job_t * job,
const hb_subtitle_config_t * subtitlecfg,
- const char *lang_code )
+ const char *lang_code, int source )
{
hb_subtitle_t *subtitle;
iso639_lang_t *lang = NULL;
subtitle->id = (hb_list_count(job->list_subtitle) << 8) | 0xFF;
subtitle->format = TEXTSUB;
- subtitle->source = SRTSUB;
- subtitle->codec = WORK_DECSRTSUB;
+ subtitle->source = source;
+ subtitle->codec = source == IMPORTSRT ? WORK_DECSRTSUB : WORK_DECSSASUB;
subtitle->timebase.num = 1;
subtitle->timebase.den = 90000;
return 1;
}
+int hb_srt_add( const hb_job_t * job,
+ const hb_subtitle_config_t * subtitlecfg,
+ const char *lang_code )
+{
+ return hb_import_subtitle_add(job, subtitlecfg, lang_code, IMPORTSRT);
+}
+
int hb_subtitle_can_force( int source )
{
return source == VOBSUB || source == PGSSUB;
int hb_subtitle_can_burn( int source )
{
- return source == VOBSUB || source == PGSSUB || source == SSASUB ||
- source == SRTSUB || source == CC608SUB || source == UTF8SUB ||
- source == TX3GSUB;
+ return source == VOBSUB || source == PGSSUB || source == SSASUB ||
+ source == CC608SUB || source == UTF8SUB || source == TX3GSUB ||
+ source == IMPORTSRT || source == IMPORTSSA;
}
int hb_subtitle_can_pass( int source, int mux )
case PGSSUB:
case VOBSUB:
case SSASUB:
- case SRTSUB:
case UTF8SUB:
case TX3GSUB:
case CC608SUB:
case CC708SUB:
+ case IMPORTSRT:
+ case IMPORTSSA:
return 1;
default:
{
case VOBSUB:
case SSASUB:
- case SRTSUB:
case UTF8SUB:
case TX3GSUB:
case CC608SUB:
case CC708SUB:
+ case IMPORTSRT:
+ case IMPORTSSA:
return 1;
default:
{
case VOBSUB:
return "VOBSUB";
- case SRTSUB:
+ case IMPORTSRT:
return "SRT";
case CC608SUB:
return "CC608";
return "UTF-8";
case TX3GSUB:
return "TX3G";
+ case IMPORTSSA:
case SSASUB:
return "SSA";
case PGSSUB:
hb_list_t *hb_subtitle_list_copy(const hb_list_t *src);
void hb_subtitle_close( hb_subtitle_t **sub );
int hb_subtitle_add(const hb_job_t * job, const hb_subtitle_config_t * subtitlecfg, int track);
+int hb_import_subtitle_add( const hb_job_t * job,
+ const hb_subtitle_config_t * subtitlecfg,
+ const char *lang_code, int source );
int hb_srt_add(const hb_job_t * job, const hb_subtitle_config_t * subtitlecfg,
const char *lang);
int hb_subtitle_can_force( int source );
hb_subtitle_config_t config;
enum subtype { PICTURESUB, TEXTSUB } format;
- enum subsource { VOBSUB, SRTSUB, CC608SUB, /*unused*/CC708SUB, UTF8SUB, TX3GSUB, SSASUB, PGSSUB } source;
+ enum subsource { VOBSUB, CC608SUB, /*unused*/CC708SUB,
+ UTF8SUB, TX3GSUB, SSASUB, PGSSUB,
+ IMPORTSRT, IMPORTSSA, SRTSUB = IMPORTSRT } source;
char lang[1024];
char iso639_2[4];
uint32_t attributes; /* Closed Caption, Childrens, Directors etc */
struct hb_work_private_s
{
- // If decoding to PICTURESUB format:
- int readOrder;
+ hb_job_t * job;
+ hb_subtitle_t * subtitle;
- hb_job_t *job;
+ // SSA Import
+ FILE * file;
+ int readOrder;
};
#define SSA_VERBOSE_PACKETS 0
style->bg_alpha = 0xFF;
}
+static int extradataInit( hb_work_private_t * pv )
+{
+ int events = 0;
+ char * events_tag = "[Events]";
+ char * format_tag = "Format:";
+ int events_len = strlen(events_tag);;
+ int format_len = strlen(format_tag);;
+ char * header = NULL;
+
+ while (1)
+ {
+ char * line = NULL;
+ size_t len, size = 0;
+
+ len = getline(&line, &size, pv->file);
+ if (len < 0)
+ {
+ // Incomplete SSA header
+ free(header);
+ return 1;
+ }
+ if (len > 0)
+ {
+ if (header != NULL)
+ {
+ char * tmp = header;
+ header = hb_strdup_printf("%s%s", header, line);
+ free(tmp);
+ }
+ else
+ {
+ header = strdup(line);
+ }
+ }
+ if (!events)
+ {
+ if (len >= events_len && !strncasecmp(line, events_tag, events_len))
+ {
+ events = 1;
+ }
+ }
+ else
+ {
+ if (len >= format_len && !strncasecmp(line, format_tag, format_len))
+ {
+ free(line);
+ break;
+ }
+ if (len > 0)
+ {
+ // Improperly formatted SSA header
+ free(header);
+ return 1;
+ }
+ }
+ free(line);
+ }
+ pv->subtitle->extradata = (uint8_t*)header;
+ pv->subtitle->extradata_size = strlen(header) + 1;
+
+ return 0;
+}
+
static int decssaInit( hb_work_object_t * w, hb_job_t * job )
{
hb_work_private_t * pv;
pv = calloc( 1, sizeof( hb_work_private_t ) );
w->private_data = pv;
- pv->job = job;
+ pv->job = job;
+ pv->subtitle = w->subtitle;
+
+ if (w->fifo_in == NULL && pv->subtitle->config.src_filename != NULL)
+ {
+ pv->file = hb_fopen(pv->subtitle->config.src_filename, "r");
+ if(pv->file == NULL)
+ {
+ hb_error("Could not open the SSA subtitle file '%s'\n",
+ pv->subtitle->config.src_filename);
+ goto fail;
+ }
+
+ // Read SSA header and store in subtitle extradata
+ if (extradataInit(pv))
+ {
+ goto fail;
+ }
+ }
+
+ return 0;
+
+fail:
+ if (pv != NULL)
+ {
+ if (pv->file != NULL)
+ {
+ fclose(pv->file);
+ }
+ free(pv);
+ w->private_data = NULL;
+ }
+ return 1;
+}
+
+#define SSA_2_HB_TIME(hr,min,sec,centi) \
+ ( 90LL * ( hr * 1000LL * 60 * 60 +\
+ min * 1000LL * 60 +\
+ sec * 1000LL +\
+ centi * 10LL ) )
+
+/*
+ * Parses the start and stop time from the specified SSA packet.
+ *
+ * Returns true if parsing failed; false otherwise.
+ */
+static int parse_timing( char *line, int64_t *start, int64_t *stop )
+{
+ /*
+ * Parse Start and End fields for timing information
+ */
+ int start_hr, start_min, start_sec, start_centi;
+ int end_hr, end_min, end_sec, end_centi;
+ // SSA subtitles have an empty layer field (bare ','). The scanf
+ // format specifier "%*128[^,]" will not match on a bare ','. There
+ // must be at least one non ',' character in the match. So the format
+ // specifier is placed directly next to the ':' so that the next
+ // expected ' ' after the ':' will be the character it matches on
+ // when there is no layer field.
+ int numPartsRead = sscanf( (char *) line, "Dialogue:%*128[^,],"
+ "%d:%d:%d.%d," // Start
+ "%d:%d:%d.%d,", // End
+ &start_hr, &start_min, &start_sec, &start_centi,
+ &end_hr, &end_min, &end_sec, &end_centi );
+ if ( numPartsRead != 8 )
+ return 1;
+
+ *start = SSA_2_HB_TIME(start_hr, start_min, start_sec, start_centi);
+ *stop = SSA_2_HB_TIME( end_hr, end_min, end_sec, end_centi);
return 0;
}
+static char * find_field( char * pos, char * end, int fieldNum )
+{
+ int curFieldID = 1;
+ while (pos < end)
+ {
+ if ( *pos++ == ',' )
+ {
+ curFieldID++;
+ if ( curFieldID == fieldNum )
+ return pos;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * SSA line format:
+ * Dialogue: Marked,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text '\0'
+ * 1 2 3 4 5 6 7 8 9 10
+ *
+ * MKV-SSA packet format:
+ * ReadOrder,Marked, Style,Name,MarginL,MarginR,MarginV,Effect,Text '\0'
+ * 1 2 3 4 5 6 7 8 9
+ */
+static hb_buffer_t *
+decode_line_to_mkv_ssa( hb_work_private_t * pv, char * line, int size )
+{
+ hb_buffer_t * out;
+
+ int64_t start, stop;
+ if (parse_timing(line, &start, &stop))
+ {
+ goto fail;
+ }
+
+ // Convert the SSA packet to MKV-SSA format, which is what libass expects
+ char * mkvSSA;
+ int numPartsRead;
+ char * styleToTextFields;
+ char * layerField = malloc(size);
+
+ // SSA subtitles have an empty layer field (bare ','). The scanf
+ // format specifier "%*128[^,]" will not match on a bare ','. There
+ // must be at least one non ',' character in the match. So the format
+ // specifier is placed directly next to the ':' so that the next
+ // expected ' ' after the ':' will be the character it matches on
+ // when there is no layer field.
+ numPartsRead = sscanf( (char *)line, "Dialogue:%128[^,],", layerField );
+ if ( numPartsRead != 1 )
+ {
+ free(layerField);
+ goto fail;
+ }
+
+ styleToTextFields = find_field( line, line + size, 4 );
+ if ( styleToTextFields == NULL ) {
+ free( layerField );
+ goto fail;
+ }
+
+ // The sscanf conversion above will result in an extra space
+ // before the layerField. Strip the space.
+ char *stripLayerField = layerField;
+ for(; *stripLayerField == ' '; stripLayerField++);
+
+ out = hb_buffer_init( size + 1 );
+ mkvSSA = (char*)out->data;
+
+ mkvSSA[0] = '\0';
+ sprintf(mkvSSA, "%d", pv->readOrder++);
+ strcat( mkvSSA, "," );
+ strcat( mkvSSA, stripLayerField );
+ strcat( mkvSSA, "," );
+ strcat( mkvSSA, (char *)styleToTextFields );
+
+ out->size = strlen(mkvSSA) + 1;
+ out->s.frametype = HB_FRAME_SUBTITLE;
+ out->s.start = start;
+ out->s.duration = stop - start;
+ out->s.stop = stop;
+
+ if( out->size == 0 )
+ {
+ hb_buffer_close(&out);
+ }
+
+ free( layerField );
+
+ return out;
+
+fail:
+ hb_log( "decssasub: malformed SSA subtitle packet: %.*s\n", size, line );
+ return NULL;
+}
+
+/*
+ * Read the SSA file and put the entries into the subtitle fifo for all to read
+ */
+static hb_buffer_t * ssa_read( hb_work_private_t * pv )
+{
+ hb_buffer_t * out;
+
+ while (!feof(pv->file))
+ {
+ char * line = NULL;
+ size_t len, size = 0;
+
+ len = getline(&line, &size, pv->file);
+ if (len > 0)
+ {
+ out = decode_line_to_mkv_ssa(pv, line, len);
+ if (out != NULL)
+ {
+ return out;
+ }
+ }
+ if (len < 0)
+ {
+ // Error or EOF
+ out = hb_buffer_eof_init();
+ return out;
+ }
+ }
+ out = hb_buffer_eof_init();
+
+ return out;
+}
+
static int decssaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_buffer_t ** buf_out )
{
- hb_buffer_t * in = *buf_in;
-
-#if SSA_VERBOSE_PACKETS
- printf("\nPACKET(%"PRId64",%"PRId64"): %.*s\n", in->s.start/90, in->s.stop/90, in->size, in->data);
-#endif
+ hb_work_private_t * pv = w->private_data;
+ hb_buffer_t * in = *buf_in;
*buf_in = NULL;
+ if (in == NULL && pv->file != NULL)
+ {
+ in = ssa_read(pv);
+ }
*buf_out = in;
if (in->s.flags & HB_BUF_FLAG_EOF)
{
hb_buffer_realloc(in, ++in->size);
in->data[in->size - 1] = '\0';
+#if SSA_VERBOSE_PACKETS
+ printf("\nPACKET(%"PRId64",%"PRId64"): %.*s\n", in->s.start/90, in->s.stop/90, in->size, in->data);
+#endif
+
return HB_WORK_OK;
}
hb_dict_t *subtitle_dict;
hb_subtitle_t *subtitle = hb_list_item(job->list_subtitle, ii);
- if (subtitle->source == SRTSUB)
+ if (subtitle->source == IMPORTSRT ||
+ subtitle->source == IMPORTSSA)
{
subtitle_dict = json_pack_ex(&error, 0,
"{s:o, s:o, s:o, s:{s:o, s:o, s:o}}",
"Default", hb_value_bool(subtitle->config.default_track),
"Burn", hb_value_bool(subtitle->config.dest == RENDERSUB),
"Offset", hb_value_int(subtitle->config.offset),
- "SRT",
+ "Import",
+ "Format", hb_value_string(subtitle->source == IMPORTSRT ?
+ "SRT" : "SSA"),
"Filename", hb_value_string(subtitle->config.src_filename),
- "Language", hb_value_string(subtitle->iso639_2),
- "Codeset", hb_value_string(subtitle->config.src_codeset));
+ "Language", hb_value_string(subtitle->iso639_2));
+ if (subtitle->source == IMPORTSRT)
+ {
+ hb_dict_t *import_dict = hb_dict_get(subtitle_dict, "Import");
+ hb_dict_set(import_dict, "Codeset",
+ hb_value_string(subtitle->config.src_codeset));
+ }
}
else
{
hb_subtitle_config_t sub_config;
int track = -1;
int burn = 0;
- const char *srtfile = NULL;
+ const char *importfile = NULL;
json_int_t offset = 0;
result = json_unpack_ex(subtitle_dict, &error, 0,
- "{s?i, s?{s:s}}",
+ "{s?i, s?{s:s}, s?{s:s}}",
"Track", unpack_i(&track),
+ // Support legacy "SRT" import
"SRT",
- "Filename", unpack_s(&srtfile));
+ "Filename", unpack_s(&importfile),
+ "Import",
+ "Filename", unpack_s(&importfile));
if (result < 0)
{
hb_error("json unpack failure: %s", error.text);
return NULL;
}
// Embedded subtitle track
- if (track >= 0 && srtfile == NULL)
+ if (track >= 0 && importfile == NULL)
{
hb_subtitle_t *subtitle;
subtitle = hb_list_item(job->title->list_subtitle, track);
hb_subtitle_add(job, &sub_config, track);
}
}
- else if (srtfile != NULL)
+ else if (importfile != NULL)
{
- strncpy(sub_config.src_filename, srtfile, 255);
+ strncpy(sub_config.src_filename, importfile, 255);
sub_config.src_filename[255] = 0;
- const char *srtlang = "und";
- const char *srtcodeset = "UTF-8";
+ const char * lang = "und";
+ const char * srtcodeset = "UTF-8";
+ const char * format = "SRT";
+ int source = IMPORTSRT;
result = json_unpack_ex(subtitle_dict, &error, 0,
- "{s?b, s?b, s?I, " // Common
- "s?{s?s, s?s, s?s}}", // SRT
+ "{s?b, s?b, s?I, " // Common
+ "s?{s?s, s?s, s?s}," // Legacy SRT settings
+ "s?{s?s, s?s, s?s, s?s}}", // Import settings
"Default", unpack_b(&sub_config.default_track),
"Burn", unpack_b(&burn),
"Offset", unpack_I(&offset),
"SRT",
- "Filename", unpack_s(&srtfile),
- "Language", unpack_s(&srtlang),
+ "Filename", unpack_s(&importfile),
+ "Language", unpack_s(&lang),
+ "Codeset", unpack_s(&srtcodeset),
+ "Import",
+ "Format", unpack_s(&format),
+ "Filename", unpack_s(&importfile),
+ "Language", unpack_s(&lang),
"Codeset", unpack_s(&srtcodeset));
if (result < 0)
{
sub_config.dest = burn ? RENDERSUB : PASSTHRUSUB;
strncpy(sub_config.src_codeset, srtcodeset, 39);
sub_config.src_codeset[39] = 0;
- hb_srt_add(job, &sub_config, srtlang);
+ if (!strcasecmp(format, "SSA"))
+ {
+ source = IMPORTSSA;
+ }
+ hb_import_subtitle_add(job, &sub_config, lang, source);
}
}
}
case CC608SUB:
case CC708SUB:
case TX3GSUB:
- case SRTSUB:
case UTF8SUB:
case SSASUB:
+ case IMPORTSRT:
+ case IMPORTSSA:
{
if (job->mux == HB_MUX_AV_MP4)
{
hb_subtitle_t *subtitle;
for (ii = 0; (subtitle = hb_list_item(r->job->list_subtitle, ii)); ++ii)
{
- if (subtitle->fifo_in && subtitle->source != SRTSUB)
+ if (subtitle->fifo_in)
+ {
push_buf(r, subtitle->fifo_in, hb_buffer_eof_init());
+ }
}
hb_log("reader: done. %d scr changes", r->demux.scr_changes);
}
return ssa_post_init( filter, job );
} break;
- case SRTSUB:
+ case IMPORTSRT:
+ case IMPORTSSA:
case UTF8SUB:
case TX3GSUB:
{
return ssa_work( filter, buf_in, buf_out );
} break;
- case SRTSUB:
+ case IMPORTSRT:
+ case IMPORTSSA:
case CC608SUB:
case UTF8SUB:
case TX3GSUB:
ssa_close( filter );
} break;
- case SRTSUB:
+ case IMPORTSRT:
+ case IMPORTSSA:
case CC608SUB:
case UTF8SUB:
case TX3GSUB:
snprintf(subtitle->lang, sizeof( subtitle->lang ), "%s [%s]",
strlen(lang->native_name) ? lang->native_name : lang->eng_name,
hb_subsource_name(subtitle->source));
- strncpy(subtitle->iso639_2, lang->iso639_2, 4);
+ strncpy(subtitle->iso639_2, lang->iso639_2, 3);
+ subtitle->iso639_2[3] = 0;
// Copy the extradata for the subtitle track
if (codecpar->extradata != NULL)
subtitle->lang, subtitle->track, subtitle->id,
subtitle->format == PICTURESUB ? "Picture" : "Text");
}
- else if( subtitle->source == SRTSUB )
+ else if (subtitle->source == IMPORTSRT)
{
/* For SRT, print offset and charset too */
hb_log(" * subtitle track %d, %s (track %d, id 0x%x, Text) -> "
// Since that number is unbounded, the FIFO must be made
// (effectively) unbounded in capacity.
subtitle->fifo_raw = hb_fifo_init( FIFO_UNBOUNDED, FIFO_UNBOUNDED_WAKE );
- if (w->id != WORK_DECSRTSUB)
+ // Check if input comes from a file.
+ if (subtitle->source != IMPORTSRT &&
+ subtitle->source != IMPORTSSA)
{
- // decsrtsub is a buffer source like reader. It's input comes
- // from a file.
subtitle->fifo_in = hb_fifo_init( FIFO_SMALL, FIFO_SMALL_WAKE );
}
if (!job->indepth_scan)
static char ** srtlang = NULL;
static int srtdefault = -1;
static int srtburn = -1;
+static char ** ssafile = NULL;
+static char ** ssaoffset = NULL;
+static char ** ssalang = NULL;
+static int ssadefault = -1;
+static int ssaburn = -1;
static int width = 0;
static int height = 0;
static int crop[4] = { -1,-1,-1,-1 };
" the video track.\n"
" If 'number' is omitted, the first SRT is burned.\n"
" 'number' is a 1-based index into the 'srt-file' list\n"
+" --ssa-file <string> SubStationAlpha SSA filename(s), separated by\n"
+" commas.\n"
+" --ssa-offset <string> Offset (in milliseconds) to apply to the SSA\n"
+" file(s), separated by commas. If not specified,\n"
+" zero is assumed. Offsets may be negative.\n"
+" --ssa-lang <string> SSA track language as an ISO 639-2 code\n"
+" (e.g. fre, eng, spa, dut, et cetera)\n"
+" If not specified, then 'und' is used.\n"
+" Separate by commas.\n"
+" --ssa-default[=number]\n"
+" Flag the selected SSA as the default subtitle\n"
+" to be displayed during playback.\n"
+" Setting no default means no subtitle will be\n"
+" automatically displayed. If 'number' is omitted,\n"
+" the first SSA is the default.\n"
+" 'number' is a 1-based index into the 'ssa-file' list\n"
+" --ssa-burn[=number] \"Burn\" the selected SSA subtitle into\n"
+" the video track.\n"
+" If 'number' is omitted, the first SSA is burned.\n"
+" 'number' is a 1-based index into the 'ssa-file' list\n"
"\n"
);
#define FILTER_LAPSHARP 314
#define FILTER_LAPSHARP_TUNE 315
#define JSON_LOGGING 316
+ #define SSA_FILE 317
+ #define SSA_OFFSET 318
+ #define SSA_LANG 319
+ #define SSA_DEFAULT 320
+ #define SSA_BURN 321
for( ;; )
{
{ "srt-lang", required_argument, NULL, SRT_LANG },
{ "srt-default", optional_argument, NULL, SRT_DEFAULT },
{ "srt-burn", optional_argument, NULL, SRT_BURN },
+ { "ssa-file", required_argument, NULL, SSA_FILE },
+ { "ssa-offset", required_argument, NULL, SSA_OFFSET },
+ { "ssa-lang", required_argument, NULL, SSA_LANG },
+ { "ssa-default", optional_argument, NULL, SSA_DEFAULT },
+ { "ssa-burn", optional_argument, NULL, SSA_BURN },
{ "native-language", required_argument, NULL,'N' },
{ "native-dub", no_argument, NULL, NATIVE_DUB },
{ "encoder", required_argument, NULL, 'e' },
srtburn = 1 ;
}
break;
+ case SSA_FILE:
+ ssafile = hb_str_vsplit( optarg, ',' );
+ break;
+ case SSA_OFFSET:
+ ssaoffset = hb_str_vsplit( optarg, ',' );
+ break;
+ case SSA_LANG:
+ ssalang = hb_str_vsplit( optarg, ',' );
+ break;
+ case SSA_DEFAULT:
+ if( optarg != NULL )
+ {
+ ssadefault = atoi( optarg );
+ }
+ else
+ {
+ ssadefault = 1 ;
+ }
+ break;
+ case SSA_BURN:
+ if( optarg != NULL )
+ {
+ ssaburn = atoi( optarg );
+ }
+ else
+ {
+ ssaburn = 1 ;
+ }
+ break;
case '2':
twoPass = 1;
break;
int64_t offset = 0;
char *iso639_2 = "und";
int burn = !*one_burned && srtburn == track + 1 &&
- hb_subtitle_can_burn(SRTSUB);
+ hb_subtitle_can_burn(IMPORTSRT);
*one_burned |= burn;
int def = srtdefault == track + 1;
hb_dict_t *subtitle_dict = hb_dict_init();
hb_dict_t *srt_dict = hb_dict_init();
- hb_dict_set(subtitle_dict, "SRT", srt_dict);
+ hb_dict_set(subtitle_dict, "Import", srt_dict);
hb_dict_set(subtitle_dict, "Default", hb_value_bool(def));
hb_dict_set(subtitle_dict, "Burn", hb_value_bool(burn));
hb_dict_set(subtitle_dict, "Offset", hb_value_int(offset));
+ hb_dict_set(srt_dict, "Format", hb_value_string("SRT"));
hb_dict_set(srt_dict, "Filename", hb_value_string(srtfile[track]));
hb_dict_set(srt_dict, "Language", hb_value_string(iso639_2));
hb_dict_set(srt_dict, "Codeset", hb_value_string(codeset));
return 0;
}
+static int add_ssa(hb_value_array_t *list, int track, int *one_burned)
+{
+ int64_t offset = 0;
+ char *iso639_2 = "und";
+ int burn = !*one_burned && ssaburn == track + 1 &&
+ hb_subtitle_can_burn(IMPORTSRT);
+ *one_burned |= burn;
+ int def = ssadefault == track + 1;
+
+ if (ssaoffset && track < hb_str_vlen(ssaoffset) && ssaoffset[track])
+ offset = strtoll(ssaoffset[track], NULL, 0);
+ if (ssalang && track < hb_str_vlen(ssalang) && ssalang[track])
+ {
+ const iso639_lang_t *lang = lang_lookup(ssalang[track]);
+ if (lang != NULL)
+ {
+ iso639_2 = lang->iso639_2;
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Invalid SRT language (%s)\n",
+ ssalang[track]);
+ }
+ }
+
+ hb_dict_t *subtitle_dict = hb_dict_init();
+ hb_dict_t *ssa_dict = hb_dict_init();
+ hb_dict_set(subtitle_dict, "Import", ssa_dict);
+ hb_dict_set(subtitle_dict, "Default", hb_value_bool(def));
+ hb_dict_set(subtitle_dict, "Burn", hb_value_bool(burn));
+ hb_dict_set(subtitle_dict, "Offset", hb_value_int(offset));
+ hb_dict_set(ssa_dict, "Format", hb_value_string("SSA"));
+ hb_dict_set(ssa_dict, "Filename", hb_value_string(ssafile[track]));
+ hb_dict_set(ssa_dict, "Language", hb_value_string(iso639_2));
+ hb_value_array_append(list, subtitle_dict);
+ return 0;
+}
+
static int add_audio(hb_value_array_t *list, hb_title_t *title, int track)
{
// Check that the track exists
add_srt(subtitle_array, ii, &one_burned);
}
}
+ if (ssafile != NULL)
+ {
+ int ii;
+ for (ii = 0; ssafile[ii] != NULL; ii++)
+ {
+ add_ssa(subtitle_array, ii, &one_burned);
+ }
+ }
return job_dict;
}
{
get
{
- return HBFunctions.hb_subtitle_can_burn((int)hb_subtitle_s_subsource.SRTSUB) > 0;
+ return HBFunctions.hb_subtitle_can_burn((int)hb_subtitle_s_subsource.IMPORTSRT) > 0;
}
}
return "CC608";
case hb_subtitle_s_subsource.CC708SUB:
return "CC708";
- case hb_subtitle_s_subsource.SRTSUB:
+ case hb_subtitle_s_subsource.IMPORTSRT:
return "SRT";
case hb_subtitle_s_subsource.SSASUB:
return "SSA";
{
VOBSUB,
- SRTSUB,
-
CC608SUB,
CC708SUB,
SSASUB,
- PGSSUB
+ PGSSUB,
+
+ IMPORTSRT,
+
+ IMPORTSSA
}
}