@@ -880,6 +880,10 @@ void parse_segment_track_entry(struct matroska_ctx *mkv_ctx)
880880 ULLONG track_number = 0 ;
881881 enum matroska_track_entry_type track_type = MATROSKA_TRACK_TYPE_VIDEO ;
882882 char * lang = strdup ("eng" );
883+ if (lang == NULL )
884+ {
885+ fatal (EXIT_NOT_ENOUGH_MEMORY , "In parse_segment_track_entry: Out of memory allocating default language." );
886+ }
883887 char * header = NULL ;
884888 char * lang_ietf = NULL ;
885889 char * codec_id_string = NULL ;
@@ -1031,29 +1035,7 @@ void parse_segment_track_entry(struct matroska_ctx *mkv_ctx)
10311035 case MATROSKA_SEGMENT_TRACK_LANGUAGE_IETF :
10321036 lang_ietf = read_vint_block_string (file );
10331037 mprint (" Language IETF: %s\n" , lang_ietf );
1034- // We'll store this for later use rather than freeing it immediately
1035- if (track_type == MATROSKA_TRACK_TYPE_SUBTITLE )
1036- {
1037- // Don't free lang_ietf here, store in track
1038- if (lang != NULL )
1039- {
1040- // If we previously allocated lang, free it as we'll prefer IETF
1041- free (lang );
1042- lang = NULL ;
1043- }
1044- // Default to "eng" if we somehow don't have a language yet
1045- if (lang == NULL )
1046- {
1047- lang = strdup ("eng" );
1048- }
1049- }
1050- else
1051- {
1052- free (lang_ietf ); // Free if not a subtitle track
1053- lang_ietf = NULL ;
1054- }
10551038 MATROSKA_SWITCH_BREAK (code , code_len );
1056-
10571039 /* Misc ids */
10581040 case MATROSKA_VOID :
10591041 read_vint_block_skip (file );
@@ -1349,22 +1331,19 @@ void parse_segment(struct matroska_ctx *mkv_ctx)
13491331
13501332char * generate_filename_from_track (struct matroska_ctx * mkv_ctx , struct matroska_sub_track * track )
13511333{
1352- // Use lang_ietf if available, otherwise fall back to lang
1353- const char * lang_to_use = track -> lang_ietf ? track -> lang_ietf : track -> lang ;
13541334 const char * basename = get_basename (mkv_ctx -> filename );
13551335 const char * extension = matroska_track_text_subtitle_id_extensions [track -> codec_id ];
1356-
1357- // Calculate needed size: basename + "_" + lang + "_" + index + "." + extension + null
1358- size_t needed = strlen (basename ) + strlen (lang_to_use ) + strlen (extension ) + 32 ;
1336+ /* Prefer the BCP-47 IETF tag (e.g. "zh-Hant") over the legacy
1337+ * ISO-639-2 code (e.g. "chi") when one is available. */
1338+ const char * lang_tag = track -> lang_ietf ? track -> lang_ietf : track -> lang ;
1339+ size_t needed = strlen (basename ) + strlen (lang_tag ) + strlen (extension ) + 32 ;
13591340 char * buf = malloc (needed );
13601341 if (buf == NULL )
13611342 fatal (EXIT_NOT_ENOUGH_MEMORY , "In generate_filename_from_track: Out of memory." );
1362-
13631343 if (track -> lang_index == 0 )
1364- snprintf (buf , needed , "%s_%s.%s" , basename , lang_to_use , extension );
1344+ snprintf (buf , needed , "%s_%s.%s" , basename , lang_tag , extension );
13651345 else
1366- snprintf (buf , needed , "%s_%s_" LLD ".%s" , basename , lang_to_use ,
1367- track -> lang_index , extension );
1346+ snprintf (buf , needed , "%s_%s_" LLD ".%s" , basename , lang_tag , track -> lang_index , extension );
13681347 return buf ;
13691348}
13701349
@@ -1599,17 +1578,18 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
15991578 }
16001579
16011580 // Generate base filename (without extension)
1602- const char * lang_to_use = track -> lang_ietf ? track -> lang_ietf : track -> lang ;
16031581 const char * basename = get_basename (mkv_ctx -> filename );
1604- size_t needed = strlen (basename ) + strlen (lang_to_use ) + 32 ;
1582+ /* Prefer the BCP-47 IETF tag over the legacy ISO-639-2 code. */
1583+ const char * lang_tag = track -> lang_ietf ? track -> lang_ietf : track -> lang ;
1584+ size_t needed = strlen (basename ) + strlen (lang_tag ) + 32 ;
16051585 char * base_filename = malloc (needed );
16061586 if (base_filename == NULL )
16071587 fatal (EXIT_NOT_ENOUGH_MEMORY , "In save_vobsub_track: Out of memory." );
16081588
16091589 if (track -> lang_index == 0 )
1610- snprintf (base_filename , needed , "%s_%s" , basename , lang_to_use );
1590+ snprintf (base_filename , needed , "%s_%s" , basename , lang_tag );
16111591 else
1612- snprintf (base_filename , needed , "%s_%s_" LLD , basename , lang_to_use , track -> lang_index );
1592+ snprintf (base_filename , needed , "%s_%s_" LLD , basename , lang_tag , track -> lang_index );
16131593
16141594 // Create .sub filename
16151595 char * sub_filename = malloc (needed + 5 );
@@ -1664,7 +1644,7 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
16641644
16651645 // Add language identifier line
16661646 char lang_line [128 ];
1667- snprintf (lang_line , sizeof (lang_line ), "\nid: %s, index: 0\n" , lang_to_use );
1647+ snprintf (lang_line , sizeof (lang_line ), "\nid: %s, index: 0\n" , track -> lang );
16681648 write_wrapped (idx_desc , lang_line , strlen (lang_line ));
16691649
16701650 // Buffer for PS/PES headers and padding
@@ -1710,7 +1690,6 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
17101690 write_wrapped (sub_desc , (char * )zero_buf , padding_needed );
17111691 bytes_written += padding_needed ;
17121692 }
1713-
17141693 file_pos += bytes_written ;
17151694 }
17161695
@@ -1932,17 +1911,21 @@ void free_sub_track(struct matroska_sub_track *track)
19321911
19331912void matroska_save_all (struct matroska_ctx * mkv_ctx , char * lang )
19341913{
1935- char * match ;
19361914 for (int i = 0 ; i < mkv_ctx -> sub_tracks_count ; i ++ )
19371915 {
19381916 if (lang )
19391917 {
1940- // Try to match against IETF tag first if available
1918+ /* Match against lang_ietf (BCP-47, e.g. "en-US") first,
1919+ * then fall back to lang (ISO-639-2, e.g. "eng").
1920+ * This lets users pass either form to --mkvlang. */
1921+ int matched = 0 ;
19411922 if (mkv_ctx -> sub_tracks [i ]-> lang_ietf &&
1942- (match = strstr (lang , mkv_ctx -> sub_tracks [i ]-> lang_ietf )) != NULL )
1943- save_sub_track (mkv_ctx , mkv_ctx -> sub_tracks [i ]);
1944- // Fall back to 3-letter code
1945- else if ((match = strstr (lang , mkv_ctx -> sub_tracks [i ]-> lang )) != NULL )
1923+ strstr (lang , mkv_ctx -> sub_tracks [i ]-> lang_ietf ) != NULL )
1924+ matched = 1 ;
1925+ if (!matched &&
1926+ strstr (lang , mkv_ctx -> sub_tracks [i ]-> lang ) != NULL )
1927+ matched = 1 ;
1928+ if (matched )
19461929 save_sub_track (mkv_ctx , mkv_ctx -> sub_tracks [i ]);
19471930 }
19481931 else
0 commit comments