[FFmpeg-devel] [PATCH] lavfi/subtitles: load attached fonts to libass.

Facundo Gaich facugaich at gmail.com
Tue Apr 8 04:35:01 CEST 2014


Videos with complex typesetting usually have font files embedded
as attachment streams. vf_subtitles now finds all attachment
streams with a MIME type associated with fonts and loads them
to libass so it can use them for rendering.

The code was basically ported from mpv's loadfile.c at 929793be7

Signed-off-by: Facundo Gaich <facugaich at gmail.com>
---
 libavfilter/vf_subtitles.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index e44f61d..8586304 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -249,11 +249,34 @@ static const AVOption subtitles_options[] = {
     {NULL},
 };
 
+static const char *font_mimetypes[] = {
+    "application/x-truetype-font",
+    "application/vnd.ms-opentype",
+    "application/x-font-ttf",
+    "application/x-font",
+    NULL
+};
+
+static int attachment_is_font(AVStream * st)
+{
+    const AVDictionaryEntry *tag = NULL;
+
+    tag = av_dict_get(st->metadata, "mimetype", NULL, AV_DICT_MATCH_CASE);
+
+    if (tag) {
+        for (int n = 0; font_mimetypes[n]; n++) {
+            if (strcmp(font_mimetypes[n], tag->value) == 0)
+                return 1;
+        }
+    }
+    return 0;
+}
+
 AVFILTER_DEFINE_CLASS(subtitles);
 
 static av_cold int init_subtitles(AVFilterContext *ctx)
 {
-    int ret, sid;
+    int ret, sid, loaded_fonts;
     AVDictionary *codec_opts = NULL;
     AVFormatContext *fmt = NULL;
     AVCodecContext *dec_ctx = NULL;
@@ -293,6 +316,34 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
     sid = ret;
     st = fmt->streams[sid];
 
+    /* Load attached fonts */
+    for (int j = 0; j < fmt->nb_streams; j++) {
+        AVStream *st = fmt->streams[j];
+        if ((st->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) &&
+            attachment_is_font(st)) {
+            const AVDictionaryEntry *tag = NULL;
+            tag = av_dict_get(st->metadata, "filename", NULL,
+                              AV_DICT_MATCH_CASE);
+
+            if (tag) {
+                av_log(ctx, AV_LOG_DEBUG, "Loading attached font: %s\n",
+                       tag->value);
+                ass_add_font(ass->library, tag->value,
+                             st->codec->extradata,
+                             st->codec->extradata_size);
+                loaded_fonts = 1;
+            } else {
+                av_log(ctx, AV_LOG_WARNING,
+                       "Font attachment has no filename, ignored.\n");
+            }
+        }
+    }
+    if (loaded_fonts) {
+        /* Ideally this would be ass_fonts_update, but it seems to be broken
+         * as of libass 0.11.1 */
+        ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
+    }
+
     /* Open decoder */
     dec_ctx = st->codec;
     dec = avcodec_find_decoder(dec_ctx->codec_id);
-- 
1.9.1



More information about the ffmpeg-devel mailing list