[FFmpeg-cvslog] lavfi/subtitles: load attached fonts to libass.
Facundo Gaich
git at videolan.org
Sun Apr 13 13:08:26 CEST 2014
ffmpeg | branch: master | Facundo Gaich <facugaich at gmail.com> | Wed Apr 9 00:18:35 2014 -0300| [7e6b3ad6930c2f1daa5c4831bbeda3fb931921e6] | committer: Clément Bœsch
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 at 929793be7
Signed-off-by: Facundo Gaich <facugaich at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7e6b3ad6930c2f1daa5c4831bbeda3fb931921e6
---
libavfilter/vf_subtitles.c | 54 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index e44f61d..bce0e9f 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);
More information about the ffmpeg-cvslog
mailing list