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

wm4 nfxjfg at googlemail.com
Sun Apr 13 12:01:50 CEST 2014


On Wed,  9 Apr 2014 00:18:35 -0300
Facundo Gaich <facugaich at gmail.com> wrote:

> 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 | 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);

Didn't test it, but looks good to me.


More information about the ffmpeg-devel mailing list