[FFmpeg-devel] [PATCH v2 4/6] avformat/matroskadec: add support for reading LanguageBCP47 element

Marth64 marth64 at proxyid.net
Wed Nov 27 08:09:25 EET 2024


Signed-off-by: Marth64 <marth64 at proxyid.net>
---
 libavformat/matroskadec.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 0e150f9138..1d895a79b0 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -60,6 +60,7 @@
 #include "libavcodec/packet_internal.h"
 
 #include "avformat.h"
+#include "avlanguage.h"
 #include "avio_internal.h"
 #include "demux.h"
 #include "dovi_isom.h"
@@ -270,6 +271,7 @@ typedef struct MatroskaTrack {
     char    *codec_id;
     EbmlBin  codec_priv;
     char    *language;
+    char    *language_bcp47;
     double time_scale;
     uint64_t default_duration;
     uint64_t flag_default;
@@ -448,7 +450,7 @@ typedef struct MatroskaDemuxContext {
 // incomplete type (6.7.2 in C90, 6.9.2 in C99).
 // Removing the sizes breaks MSVC.
 static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19],
-                  matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2],
+                  matroska_track[34], matroska_track_encoding[6], matroska_track_encodings[2],
                   matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2],
                   matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2],
                   matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2],
@@ -616,6 +618,7 @@ static EbmlSyntax matroska_track[] = {
     { MATROSKA_ID_CODECPRIVATE,          EBML_BIN,   0, 0, offsetof(MatroskaTrack, codec_priv) },
     { MATROSKA_ID_CODECDELAY,            EBML_UINT,  0, 0, offsetof(MatroskaTrack, codec_delay),  { .u = 0 } },
     { MATROSKA_ID_TRACKLANGUAGE,         EBML_STR,   0, 0, offsetof(MatroskaTrack, language),     { .s = "eng" } },
+    { MATROSKA_ID_TRACKLANGUAGEBCP47,    EBML_STR,   0, 0, offsetof(MatroskaTrack, language_bcp47) },
     { MATROSKA_ID_TRACKDEFAULTDURATION,  EBML_UINT,  0, 0, offsetof(MatroskaTrack, default_duration) },
     { MATROSKA_ID_TRACKTIMECODESCALE,    EBML_FLOAT, 0, 0, offsetof(MatroskaTrack, time_scale),   { .f = 1.0 } },
     { MATROSKA_ID_TRACKFLAGCOMMENTARY,   EBML_UINT,  0, 0, offsetof(MatroskaTrack, flag_comment), { .u = 0 } },
@@ -3223,8 +3226,29 @@ static int matroska_parse_tracks(AVFormatContext *s)
                         AV_DICT_DONT_STRDUP_VAL);
         }
 
-        if (strcmp(track->language, "und"))
+        if (track->language_bcp47) {
+            char *bcp47_parsed_language;
+            char **bcp47_parsed_subtags;
+            int bcp47_parsed_nb_subtags;
+
+            ret = ff_bcp47_parse(track->language_bcp47, &bcp47_parsed_language,
+                                 &bcp47_parsed_subtags, &bcp47_parsed_nb_subtags);
+            if (ret < 0 && ret != AVERROR_INVALIDDATA) {
+                return ret;
+            } else if (!ret) {
+                av_dict_set(&st->metadata, "language", bcp47_parsed_language, 0);
+
+                if (bcp47_parsed_nb_subtags) {
+                    av_dict_set(&st->metadata, "language_bcp47", track->language_bcp47, 0);
+
+                    for (int i = 0; i < bcp47_parsed_nb_subtags; i++)
+                        av_free(bcp47_parsed_subtags[i]);
+                    av_freep(&bcp47_parsed_subtags);
+                }
+            }
+        } else if (strcmp(track->language, "und")) {
             av_dict_set(&st->metadata, "language", track->language, 0);
+        }
         av_dict_set(&st->metadata, "title", track->name, 0);
 
         if (track->time_scale < 0.01) {
-- 
2.34.1



More information about the ffmpeg-devel mailing list