aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFacundo Gaich <facugaich@gmail.com>2014-04-09 00:18:35 -0300
committerClément Bœsch <u@pkh.me>2014-04-13 12:06:24 +0200
commit7e6b3ad6930c2f1daa5c4831bbeda3fb931921e6 (patch)
treee80bb97f734f157a2d83d3a82a1446fbeb429d03
parent88c4e5a049aa42a3c005cae5eff7cc7718c6f3b0 (diff)
downloadffmpeg-7e6b3ad6930c2f1daa5c4831bbeda3fb931921e6.tar.gz
lavfi/subtitles: load attached fonts to libass.
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@929793be7 Signed-off-by: Facundo Gaich <facugaich@gmail.com>
-rw-r--r--libavfilter/vf_subtitles.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index e44f61ddcd..bce0e9fe1b 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -107,7 +107,6 @@ static av_cold int init(AVFilterContext *ctx)
return AVERROR(EINVAL);
}
- ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
return 0;
}
@@ -218,6 +217,9 @@ static av_cold int init_ass(AVFilterContext *ctx)
if (ret < 0)
return ret;
+ /* Initialize fonts */
+ ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
+
ass->track = ass_read_file(ass->library, ass->filename, NULL);
if (!ass->track) {
av_log(ctx, AV_LOG_ERROR,
@@ -249,11 +251,34 @@ static const AVOption subtitles_options[] = {
{NULL},
};
+static const char *font_mimetypes[] = {
+ "application/x-truetype-font",
+ "application/vnd.ms-opentype",
+ "application/x-font-ttf",
+ NULL
+};
+
+static int attachment_is_font(AVStream * st)
+{
+ const AVDictionaryEntry *tag = NULL;
+ int n;
+
+ tag = av_dict_get(st->metadata, "mimetype", NULL, AV_DICT_MATCH_CASE);
+
+ if (tag) {
+ for (n = 0; font_mimetypes[n]; n++) {
+ if (av_strcasecmp(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 j, ret, sid;
AVDictionary *codec_opts = NULL;
AVFormatContext *fmt = NULL;
AVCodecContext *dec_ctx = NULL;
@@ -293,6 +318,31 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
sid = ret;
st = fmt->streams[sid];
+ /* Load attached fonts */
+ for (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);
+ } else {
+ av_log(ctx, AV_LOG_WARNING,
+ "Font attachment has no filename, ignored.\n");
+ }
+ }
+ }
+
+ /* Initialize fonts */
+ ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
+
/* Open decoder */
dec_ctx = st->codec;
dec = avcodec_find_decoder(dec_ctx->codec_id);