summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Stebbins <[email protected]>2019-07-12 14:06:18 -0700
committerJohn Stebbins <[email protected]>2019-09-10 09:09:52 -0700
commited346b4659a7c353cc3f0aee745344e84c051e27 (patch)
tree7bb4b8f073704d4d42a20fd18e2d7dd29a1c48cf
parent53d6226c58e9f7bba23f1746bad1d8b61ec6338d (diff)
Create separate fake iso639 "any" entry
Allows us to distinguish a selection of "any" which means match any language from "und" which means the language is not known. Fixes https://github.com/HandBrake/HandBrake/issues/731
-rw-r--r--gtk/src/hb-backend.c25
-rw-r--r--libhb/lang.c73
-rw-r--r--libhb/lang.h9
-rw-r--r--libhb/preset.c32
-rw-r--r--macosx/HBLanguagesSelection.m13
5 files changed, 94 insertions, 58 deletions
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index 9f842ee89..e54b8964f 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -2000,16 +2000,16 @@ language_opts_set(signal_user_data_t *ud, const gchar *name,
(void)data; // Silence "unused variable" warning
GtkTreeIter iter;
GtkListStore *store;
- gint ii;
GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, name));
store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
const iso639_lang_t *iso639;
- for (iso639 = lang_get_next(NULL), ii = 0; iso639 != NULL;
- iso639 = lang_get_next(iso639), ii++)
+ for (iso639 = lang_get_next(NULL); iso639 != NULL;
+ iso639 = lang_get_next(iso639))
{
- gchar *lang;
+ int index = lang_lookup_index(iso639->iso639_1);
+ gchar * lang;
if (iso639->native_name[0] != 0)
lang = g_strdup_printf("%s", iso639->native_name);
@@ -2021,7 +2021,7 @@ language_opts_set(signal_user_data_t *ud, const gchar *name,
0, lang,
1, TRUE,
2, iso639->iso639_2,
- 3, (gdouble)ii,
+ 3, (gdouble)index,
-1);
g_free(lang);
}
@@ -3050,22 +3050,17 @@ void ghb_init_lang_list(GtkTreeView *tv, signal_user_data_t *ud)
{
GtkTreeIter iter;
GtkTreeStore * ts;
- int ii;
ghb_init_lang_list_model(tv);
ts = GTK_TREE_STORE(gtk_tree_view_get_model(tv));
const iso639_lang_t *iso639;
- for (iso639 = lang_get_next(NULL), ii = 0; iso639 != NULL;
- iso639 = lang_get_next(iso639), ii++)
+ for (iso639 = lang_get_any(); iso639 != NULL;
+ iso639 = lang_get_next(iso639))
{
+ int index = lang_lookup_index(iso639->iso639_2);
const char * lang;
- if (ii == 0)
- {
- lang = _("Any");
- }
- else if (iso639->native_name != NULL &&
- iso639->native_name[0] != 0)
+ if (iso639->native_name != NULL && iso639->native_name[0] != 0)
{
lang = iso639->native_name;
}
@@ -3074,7 +3069,7 @@ void ghb_init_lang_list(GtkTreeView *tv, signal_user_data_t *ud)
lang = iso639->eng_name;
}
gtk_tree_store_append(ts, &iter, NULL);
- gtk_tree_store_set(ts, &iter, 0, lang, 1, ii, -1);
+ gtk_tree_store_set(ts, &iter, 0, lang, 1, index, -1);
}
}
diff --git a/libhb/lang.c b/libhb/lang.c
index c7a7e47e1..cd3c8887f 100644
--- a/libhb/lang.c
+++ b/libhb/lang.c
@@ -11,6 +11,10 @@
#include <string.h>
#include <ctype.h>
+// Fake iso639 entry to deal with selection of "any" language
+static iso639_lang_t lang_any =
+ { "Any", "", "", "any" };
+
static const iso639_lang_t languages[] =
{ { "Unknown", "", "", "und" },
{ "Afar", "Qafar", "aa", "aar" },
@@ -207,21 +211,26 @@ const int lang_lookup_index( const char * str )
int ii = 0;
const iso639_lang_t * lang;
- // We use "Any" as a synonym for undefined
- if (!strcasecmp("any", str))
+ // We use fake lang_any iso639 to designate a match for "Any" language
+ if ((lang_any.iso639_1 && !strcasecmp(lang_any.iso639_1, str)) ||
+ (lang_any.iso639 && !strcasecmp(lang_any.iso639, str)) ||
+ (lang_any.iso639_2 && !strcasecmp(lang_any.iso639_2, str)) ||
+ (lang_any.iso639_2b && !strcasecmp(lang_any.iso639_2b, str)) ||
+ (lang_any.eng_name && !strcasecmp(lang_any.eng_name, str)) ||
+ (lang_any.native_name && !strcasecmp(lang_any.native_name, str)))
{
- return 0;
+ return -1;
}
for (ii = 0; languages[ii].eng_name; ii++)
{
lang = &languages[ii];
- if ((lang->iso639_1 != NULL && !strcasecmp(lang->iso639_1, str)) ||
- (lang->iso639 != NULL && !strcasecmp(lang->iso639, str)) ||
- (lang->iso639_2 != NULL && !strcasecmp(lang->iso639_2, str)) ||
- (lang->iso639_2b != NULL && !strcasecmp(lang->iso639_2b, str)) ||
- (lang->eng_name != NULL && !strcasecmp(lang->eng_name, str)) ||
- (lang->native_name != NULL && !strcasecmp(lang->native_name, str)))
+ if ((lang->iso639_1 && !strcasecmp(lang->iso639_1, str)) ||
+ (lang->iso639 && !strcasecmp(lang->iso639, str)) ||
+ (lang->iso639_2 && !strcasecmp(lang->iso639_2, str)) ||
+ (lang->iso639_2b && !strcasecmp(lang->iso639_2b, str)) ||
+ (lang->eng_name && !strcasecmp(lang->eng_name, str)) ||
+ (lang->native_name && !strcasecmp(lang->native_name, str)))
{
return ii;
}
@@ -237,6 +246,9 @@ const iso639_lang_t * lang_lookup( const char * str )
const iso639_lang_t * lang_for_index( int index )
{
+ if (index == -1)
+ return &lang_any;
+
if (index < 0 || index >= lang_count)
return NULL;
@@ -251,15 +263,21 @@ iso639_lang_t * lang_for_code( int code )
code_string[0] = tolower( ( code >> 8 ) & 0xFF );
code_string[1] = tolower( code & 0xFF );
- for( lang = (iso639_lang_t*) languages; lang->eng_name; lang++ )
+ if ((lang_any.iso639_1 && !strncmp(lang_any.iso639_1, code_string, 2)) ||
+ (lang_any.iso639 && !strncmp(lang_any.iso639, code_string, 2)))
+ {
+ return &lang_any;
+ }
+ for (lang = (iso639_lang_t*) languages; lang->eng_name; lang++)
{
- if( !strncmp( lang->iso639_1, code_string, 2 ) ||
- (lang->iso639 != NULL && !strncmp(lang->iso639, code_string, 2)) )
+ if ((lang->iso639_1 && !strncmp( lang->iso639_1, code_string, 2)) ||
+ (lang->iso639 && !strncmp(lang->iso639, code_string, 2)))
{
return lang;
}
}
+ // Not found, return "Unknown"
return (iso639_lang_t*) languages;
}
@@ -273,18 +291,22 @@ iso639_lang_t * lang_for_code2( const char *code )
code_string[2] = tolower( code[2] );
code_string[3] = 0;
+ if ((lang_any.iso639_2 && !strcmp(lang_any.iso639_2, code_string)) ||
+ (lang_any.iso639_2b && !strcmp(lang_any.iso639_2b, code_string)))
+ {
+ return &lang_any;
+ }
+
for( lang = (iso639_lang_t*) languages; lang->eng_name; lang++ )
{
- if( !strcmp( lang->iso639_2, code_string ) )
- {
- return lang;
- }
- if( lang->iso639_2b && !strcmp( lang->iso639_2b, code_string ) )
+ if ((lang->iso639_2 && !strcmp(lang->iso639_2, code_string)) ||
+ (lang->iso639_2b && !strcmp(lang->iso639_2b, code_string)))
{
return lang;
}
}
+ // Not found, return "Unknown"
return (iso639_lang_t*) languages;
}
@@ -302,20 +324,30 @@ iso639_lang_t * lang_for_english( const char * english )
{
iso639_lang_t * lang;
- for( lang = (iso639_lang_t*) languages; lang->eng_name; lang++ )
+ if (!strcmp(lang_any.eng_name, english))
+ {
+ return &lang_any;
+ }
+ for (lang = (iso639_lang_t*) languages; lang->eng_name; lang++)
{
- if( !strcmp( lang->eng_name, english ) )
+ if (!strcmp(lang->eng_name, english))
{
return lang;
}
}
+ // Not found, return "Unknown"
return (iso639_lang_t*) languages;
}
+const iso639_lang_t* lang_get_any(void)
+{
+ return &lang_any;
+}
+
const iso639_lang_t* lang_get_next(const iso639_lang_t *last)
{
- if (last == NULL)
+ if (last == NULL || last == &lang_any)
{
return (const iso639_lang_t*)languages;
}
@@ -327,4 +359,3 @@ const iso639_lang_t* lang_get_next(const iso639_lang_t *last)
return ++last;
}
-
diff --git a/libhb/lang.h b/libhb/lang.h
index ed3e08e5b..9017de066 100644
--- a/libhb/lang.h
+++ b/libhb/lang.h
@@ -44,6 +44,15 @@ int lang_to_code(const iso639_lang_t *lang);
iso639_lang_t * lang_for_english( const char * english );
/*
+ * Get fake iso639 cooresponding to "Any"
+ * "Any" is used when a match for any language is desired.
+ *
+ * Calling lang_get_next() with pointer returned by lang_get_any()
+ * returns the first entry in the languages list
+ */
+const iso639_lang_t* lang_get_any(void);
+
+/*
* Get the next language in the list.
* Returns NULL if there are no more languages.
* Pass NULL to get the first language in the list.
diff --git a/libhb/preset.c b/libhb/preset.c
index be4d773db..057de4ec0 100644
--- a/libhb/preset.c
+++ b/libhb/preset.c
@@ -11,6 +11,7 @@
#include "hb.h"
#include "hb_dict.h"
#include "plist.h"
+#include "lang.h"
#if HB_PROJECT_FEATURE_QSV
#include "qsv_common.h"
@@ -401,8 +402,9 @@ static hb_dict_t * source_audio_track_used(hb_dict_t *track_dict, int track)
static int find_audio_track(const hb_title_t *title,
const char *lang, int start, int behavior)
{
- hb_audio_config_t * audio;
- int ii, count;
+ hb_audio_config_t * audio;
+ int ii, count;
+ const iso639_lang_t * lang_any = lang_get_any();
count = hb_list_count(title->list_audio);
for (ii = start; ii < count; ii++)
@@ -416,7 +418,8 @@ static int find_audio_track(const hb_title_t *title,
if ((behavior == 2 ||
audio->lang.attributes == HB_AUDIO_ATTR_NONE ||
(audio->lang.attributes & HB_AUDIO_ATTR_REGULAR_MASK)) &&
- (!strcmp(lang, audio->lang.iso639_2) || !strcmp(lang, "und")))
+ (!strcmp(lang, audio->lang.iso639_2) ||
+ !strcmp(lang, lang_any->iso639_2)))
{
return ii;
}
@@ -861,11 +864,13 @@ int hb_preset_job_add_audio(hb_handle_t *h, int title_index,
add_audio_for_lang(list, preset, title, mux, copy_mask, fallback,
lang, behavior, mode, track_dict);
}
- // If no audios found, try "und" language option
+ // If no audios found, try "any" language option
+ // This can happen if AudioLanguageList is empty or if no audio
+ // matches the users preferred languages in AudioLanguageList
if (hb_value_array_len(list) <= 0)
{
add_audio_for_lang(list, preset, title, mux, copy_mask, fallback,
- "und", behavior, mode, track_dict);
+ "any", behavior, mode, track_dict);
}
hb_dict_free(&track_dict);
return 0;
@@ -875,14 +880,16 @@ int hb_preset_job_add_audio(hb_handle_t *h, int title_index,
static int find_subtitle_track(const hb_title_t *title,
const char *lang, int start)
{
- hb_subtitle_t * subtitle;
- int ii, count;
+ hb_subtitle_t * subtitle;
+ int ii, count;
+ const iso639_lang_t * lang_any = lang_get_any();
count = hb_list_count(title->list_subtitle);
for (ii = start; ii < count; ii++)
{
subtitle = hb_list_item(title->list_subtitle, ii);
- if (!strcmp(lang, subtitle->iso639_2) || !strcmp(lang, "und"))
+ if (!strcmp(lang, subtitle->iso639_2) ||
+ !strcmp(lang, lang_any->iso639_2))
{
return ii;
}
@@ -1091,14 +1098,16 @@ int hb_preset_job_add_subtitles(hb_handle_t *h, int title_index,
// Add tracks for all languages in the language list
- hb_value_array_t *lang_list = hb_dict_get(preset, "SubtitleLanguageList");
+ hb_value_array_t * lang_list = hb_dict_get(preset, "SubtitleLanguageList");
+ const iso639_lang_t * lang_any = lang_get_any();
+ const char * pref_lang = lang_any->iso639_2;
+
count = hb_value_array_len(lang_list);
- const char *pref_lang = "und";
if (count > 0)
{
pref_lang = hb_value_get_string(hb_value_array_get(lang_list, 0));
}
- if (!strcmp(pref_lang, "und"))
+ if (!strcmp(pref_lang, lang_any->iso639_2))
{
if (first_audio_lang != NULL)
{
@@ -1163,6 +1172,7 @@ int hb_preset_job_add_subtitles(hb_handle_t *h, int title_index,
}
if (count <= 0)
{
+ // No matching language. Try "Unknown" language
add_subtitle_for_lang(list, title, mux, "und", &behavior);
}
}
diff --git a/macosx/HBLanguagesSelection.m b/macosx/HBLanguagesSelection.m
index 566d8266e..3fedddd6d 100644
--- a/macosx/HBLanguagesSelection.m
+++ b/macosx/HBLanguagesSelection.m
@@ -68,8 +68,8 @@
NSMutableArray<HBLang *> *internal = [[NSMutableArray alloc] init];
NSMutableArray<HBLang *> *selected = [[NSMutableArray alloc] init];
- const iso639_lang_t *lang = lang_get_next(NULL);
- for (lang = lang_get_next(lang); lang != NULL; lang = lang_get_next(lang))
+ const iso639_lang_t *lang;
+ for (lang = lang_get_any(); lang != NULL; lang = lang_get_next(lang))
{
NSString *nativeLanguage = strlen(lang->native_name) ? @(lang->native_name) : @(lang->eng_name);
@@ -87,15 +87,6 @@
}
- // Add the (Any) item.
- HBLang *item = [[HBLang alloc] initWithLanguage:NSLocalizedString(@"(Any)", @"Language selection")
- iso639_2code:@"und"];
- if ([languages containsObject:item.iso639_2])
- {
- item.isSelected = YES;
- }
- [internal insertObject:item atIndex:0];
-
// Insert the selected items
// in the original order.
[selected sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {