[FFmpeg-devel] [PATCH] lavfi/subtitles: load attached fonts to libass.
wm4
nfxjfg at googlemail.com
Tue Apr 8 15:06:53 CEST 2014
On Tue, 8 Apr 2014 14:42:52 +0200
Clément Bœsch <u at pkh.me> wrote:
> On Mon, Apr 07, 2014 at 11:35:01PM -0300, Facundo Gaich 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 | 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
Looks exactly like the font mime type list in mpv. Note that
'application/x-font' probably never existed officially (e.g. it's not
in Haali's matroska demuxer), and is probably wrong. On the other hand,
it's probably not harmful to have this entry.
> > +};
> > +
> > +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++) {
>
> int should be out of the loop (it's not supported by all the compilers
> FFmpeg supports).
>
> > + if (strcmp(font_mimetypes[n], tag->value) == 0)
I think mime types are usually not case sensitive, so this catches
fonts with lowercase mime types only.
> > + 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++) {
>
> ditto
>
> > + AVStream *st = fmt->streams[j];
> > + if ((st->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) &&
>
> Extra parenthesis
>
> > + 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 */
>
> Can you add a bug id or something for reference in the comment?
IMO not really a bug. ass_fonts_update() literally just calls
FcConfigBuildFonts, i.e. it updates the system fonts.
ass_set_fonts on the other hand adds fonts from ASS_Library to
ASS_Renderer.
(It's worth noticing that libass wants to remove the separation between
ASS_Library and ASS_Renderer, so the need for the API call will
probably be removed once that is done.)
> > + ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
> > + }
> > +
> > /* Open decoder */
> > dec_ctx = st->codec;
> > dec = avcodec_find_decoder(dec_ctx->codec_id);
>
> Otherwise it looks OK.
>
More information about the ffmpeg-devel
mailing list