mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-04-05 21:51:23 +00:00
[FIX] Fix ownership of default Matroska track language (#2193)
* Fix ownership of default Matroska track language * matroska: restore lang_ietf preference in filename gen and lang matching Restore the working IETF language preference that was accidentally removed in the previous commit: - generate_filename_from_track(): use lang_ietf ? lang_ietf : lang for buffer sizing and both snprintf calls - save_vobsub_track(): same lang_tag pattern for base filename - matroska_save_all(): check lang_ietf first (BCP-47), fall back to lang (ISO-639-2) when --mkvlang filter is active; remove now-unused char *match variable The strdup NULL check and broken switch-case removal from the prior commit are unchanged. * matroska: fix clang-format style * matroska: fix filename underscores, LLD macro, braces, param name
This commit is contained in:
@@ -880,6 +880,10 @@ void parse_segment_track_entry(struct matroska_ctx *mkv_ctx)
|
||||
ULLONG track_number = 0;
|
||||
enum matroska_track_entry_type track_type = MATROSKA_TRACK_TYPE_VIDEO;
|
||||
char *lang = strdup("eng");
|
||||
if (lang == NULL)
|
||||
{
|
||||
fatal(EXIT_NOT_ENOUGH_MEMORY, "In parse_segment_track_entry: Out of memory allocating default language.");
|
||||
}
|
||||
char *header = NULL;
|
||||
char *lang_ietf = NULL;
|
||||
char *codec_id_string = NULL;
|
||||
@@ -1031,29 +1035,7 @@ void parse_segment_track_entry(struct matroska_ctx *mkv_ctx)
|
||||
case MATROSKA_SEGMENT_TRACK_LANGUAGE_IETF:
|
||||
lang_ietf = read_vint_block_string(file);
|
||||
mprint(" Language IETF: %s\n", lang_ietf);
|
||||
// We'll store this for later use rather than freeing it immediately
|
||||
if (track_type == MATROSKA_TRACK_TYPE_SUBTITLE)
|
||||
{
|
||||
// Don't free lang_ietf here, store in track
|
||||
if (lang != NULL)
|
||||
{
|
||||
// If we previously allocated lang, free it as we'll prefer IETF
|
||||
free(lang);
|
||||
lang = NULL;
|
||||
}
|
||||
// Default to "eng" if we somehow don't have a language yet
|
||||
if (lang == NULL)
|
||||
{
|
||||
lang = strdup("eng");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free(lang_ietf); // Free if not a subtitle track
|
||||
lang_ietf = NULL;
|
||||
}
|
||||
MATROSKA_SWITCH_BREAK(code, code_len);
|
||||
|
||||
/* Misc ids */
|
||||
case MATROSKA_VOID:
|
||||
read_vint_block_skip(file);
|
||||
@@ -1349,22 +1331,19 @@ void parse_segment(struct matroska_ctx *mkv_ctx)
|
||||
|
||||
char *generate_filename_from_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_track *track)
|
||||
{
|
||||
// Use lang_ietf if available, otherwise fall back to lang
|
||||
const char *lang_to_use = track->lang_ietf ? track->lang_ietf : track->lang;
|
||||
const char *basename = get_basename(mkv_ctx->filename);
|
||||
const char *extension = matroska_track_text_subtitle_id_extensions[track->codec_id];
|
||||
|
||||
// Calculate needed size: basename + "_" + lang + "_" + index + "." + extension + null
|
||||
size_t needed = strlen(basename) + strlen(lang_to_use) + strlen(extension) + 32;
|
||||
/* Prefer the BCP-47 IETF tag (e.g. "zh-Hant") over the legacy
|
||||
* ISO-639-2 code (e.g. "chi") when one is available. */
|
||||
const char *lang_tag = track->lang_ietf ? track->lang_ietf : track->lang;
|
||||
size_t needed = strlen(basename) + strlen(lang_tag) + strlen(extension) + 32;
|
||||
char *buf = malloc(needed);
|
||||
if (buf == NULL)
|
||||
fatal(EXIT_NOT_ENOUGH_MEMORY, "In generate_filename_from_track: Out of memory.");
|
||||
|
||||
if (track->lang_index == 0)
|
||||
snprintf(buf, needed, "%s_%s.%s", basename, lang_to_use, extension);
|
||||
snprintf(buf, needed, "%s_%s.%s", basename, lang_tag, extension);
|
||||
else
|
||||
snprintf(buf, needed, "%s_%s_" LLD ".%s", basename, lang_to_use,
|
||||
track->lang_index, extension);
|
||||
snprintf(buf, needed, "%s_%s_" LLD ".%s", basename, lang_tag, track->lang_index, extension);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -1599,17 +1578,18 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
|
||||
}
|
||||
|
||||
// Generate base filename (without extension)
|
||||
const char *lang_to_use = track->lang_ietf ? track->lang_ietf : track->lang;
|
||||
const char *basename = get_basename(mkv_ctx->filename);
|
||||
size_t needed = strlen(basename) + strlen(lang_to_use) + 32;
|
||||
/* Prefer the BCP-47 IETF tag over the legacy ISO-639-2 code. */
|
||||
const char *lang_tag = track->lang_ietf ? track->lang_ietf : track->lang;
|
||||
size_t needed = strlen(basename) + strlen(lang_tag) + 32;
|
||||
char *base_filename = malloc(needed);
|
||||
if (base_filename == NULL)
|
||||
fatal(EXIT_NOT_ENOUGH_MEMORY, "In save_vobsub_track: Out of memory.");
|
||||
|
||||
if (track->lang_index == 0)
|
||||
snprintf(base_filename, needed, "%s_%s", basename, lang_to_use);
|
||||
snprintf(base_filename, needed, "%s_%s", basename, lang_tag);
|
||||
else
|
||||
snprintf(base_filename, needed, "%s_%s_" LLD, basename, lang_to_use, track->lang_index);
|
||||
snprintf(base_filename, needed, "%s_%s_" LLD, basename, lang_tag, track->lang_index);
|
||||
|
||||
// Create .sub filename
|
||||
char *sub_filename = malloc(needed + 5);
|
||||
@@ -1664,7 +1644,7 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
|
||||
|
||||
// Add language identifier line
|
||||
char lang_line[128];
|
||||
snprintf(lang_line, sizeof(lang_line), "\nid: %s, index: 0\n", lang_to_use);
|
||||
snprintf(lang_line, sizeof(lang_line), "\nid: %s, index: 0\n", track->lang);
|
||||
write_wrapped(idx_desc, lang_line, strlen(lang_line));
|
||||
|
||||
// Buffer for PS/PES headers and padding
|
||||
@@ -1710,7 +1690,6 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
|
||||
write_wrapped(sub_desc, (char *)zero_buf, padding_needed);
|
||||
bytes_written += padding_needed;
|
||||
}
|
||||
|
||||
file_pos += bytes_written;
|
||||
}
|
||||
|
||||
@@ -1932,17 +1911,21 @@ void free_sub_track(struct matroska_sub_track *track)
|
||||
|
||||
void matroska_save_all(struct matroska_ctx *mkv_ctx, char *lang)
|
||||
{
|
||||
char *match;
|
||||
for (int i = 0; i < mkv_ctx->sub_tracks_count; i++)
|
||||
{
|
||||
if (lang)
|
||||
{
|
||||
// Try to match against IETF tag first if available
|
||||
/* Match against lang_ietf (BCP-47, e.g. "en-US") first,
|
||||
* then fall back to lang (ISO-639-2, e.g. "eng").
|
||||
* This lets users pass either form to --mkvlang. */
|
||||
int matched = 0;
|
||||
if (mkv_ctx->sub_tracks[i]->lang_ietf &&
|
||||
(match = strstr(lang, mkv_ctx->sub_tracks[i]->lang_ietf)) != NULL)
|
||||
save_sub_track(mkv_ctx, mkv_ctx->sub_tracks[i]);
|
||||
// Fall back to 3-letter code
|
||||
else if ((match = strstr(lang, mkv_ctx->sub_tracks[i]->lang)) != NULL)
|
||||
strstr(lang, mkv_ctx->sub_tracks[i]->lang_ietf) != NULL)
|
||||
matched = 1;
|
||||
if (!matched &&
|
||||
strstr(lang, mkv_ctx->sub_tracks[i]->lang) != NULL)
|
||||
matched = 1;
|
||||
if (matched)
|
||||
save_sub_track(mkv_ctx, mkv_ctx->sub_tracks[i]);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user